【问题标题】:error: strcpy was not declared in this scope错误:未在此范围内声明 strcpy
【发布时间】:2010-02-08 10:14:10
【问题描述】:

我在 Ubuntu g++ 版本 4.4.3 中编译的 c++ 问题中遇到了这个问题。 我不知道要包含哪些标题来解决这个问题。谢谢

centro_medico.cpp: In constructor ‘Centro_medico::Centro_medico(char*, char*, int, int, float)’:
centro_medico.cpp:5: error: ‘strcpy’ was not declared in this scope
centro_medico.cpp:13: warning: deprecated conversion from string constant to ‘char*’
centro_medico.cpp:13: warning: deprecated conversion from string constant to ‘char*’
centro_medico.cpp: In member function ‘Centro_medico& Centro_medico::operator=(const Centro_medico&)’:
centro_medico.cpp:26: error: ‘strcpy’ was not declared in this scope
centro_medico.cpp:39: warning: deprecated conversion from string constant to ‘char*’
centro_medico.cpp:39: warning: deprecated conversion from string constant to ‘char*’
centro_medico.cpp: In member function ‘bool Centro_medico::quitar_medico(int)’:
centro_medico.cpp:92: warning: deprecated conversion from string constant to ‘char*’
centro_medico.cpp:92: warning: deprecated conversion from string constant to ‘char*’
centro_medico.cpp: In member function ‘void Centro_medico::mostrar_especialidades(std::ostream&) const’:
centro_medico.cpp:123: error: ‘strcmpi’ was not declared in this scope
centro_medico.cpp: In member function ‘void Centro_medico::mostrar_horarios_consulta(char*) const’:
centro_medico.cpp:162: error: ‘strcmpi’ was not declared in this scope
centro_medico.cpp: In member function ‘void Centro_medico::crea_medicos()’:
centro_medico.cpp:321: warning: deprecated conversion from string constant to ‘char*’
centro_medico.cpp:321: warning: deprecated conversion from string constant to ‘char*’

medico.cpp

#include "medico.h"
#include <cstdlib>
#include <iostream>
#include <stdlib>  
#include<cstring>
#include<string>

long Medico::total_consultas=0; 
Medico::Medico(char *nom,char * espe,int colegiado,int trabajo)
{
int i;
strcpy(nombre,nom);
strcpy(especialidad,espe);
num_colegiado=colegiado;
num_horas_diarias=trabajo;
citas_medico= new Cita*[5]; // 5 Días de las semana, de Lunes a Viernes.
for (i=0;i<5;i++)
citas_medico[i]=new Cita[num_horas_diarias];
}



Medico::Medico(const Medico &m){
  int i;
  citas_medico=new Cita*[5];
  for (i=0;i<5;i++)
   citas_medico[i]=NULL;
 (*this) = m;
}

Medico &Medico::operator=(const Medico &m){
 int i,j;
 if (this != &m) { // Para evitar la asignación de un objeto a sí mismo
     strcpy(nombre,m.nombre);
     strcpy(especialidad,m.especialidad);     
     num_colegiado=m.num_colegiado;
     num_horas_diarias=m.num_horas_diarias;
     for (i=0;i<5;i++){
      delete citas_medico[i]; 
      citas_medico[i]=new Cita[num_horas_diarias];
      for(j=0;j<num_horas_diarias;j++){
       citas_medico[i][j] = m.citas_medico[i][j] ;
       }
     }     
  }
 return *this;
}

medico.h

#pragma once
#include <cstdlib>
#include <iostream>
using namespace std;
#include "cita.h"

class Medico
{
 private:
                char nombre[50];
                char especialidad[50];
                int num_colegiado;
                int num_horas_diarias;
                Cita **citas_medico;
                static long total_consultas;                
 public:
                void mostrar_calendario_citas(ostream &o=cout) const;
                bool asignar_cita(int d, int hor,Paciente *p=NULL);
                void anular_cita(int d, int hor);
                bool consultar_cita(char dni[10], int modificar=0);
                void modificar_cita(int d, int hor);                
                void vaciar_calendario_citas();
                void borrar_calendario_citas();                
                char* get_especialidad(char espec[50]) const;
                char* get_nombre(char n[50]) const;
                int get_num_colegiado() const;
                int get_num_horas() const;
                void set_num_horas(int horas);
                void mostrar_info(ostream &o=cout) const;
                static long get_total_consultas();
                Cita* operator[](int dia);
                void eliminar_calendario_citas();
                void crear_calendario_citas();    
                Medico(char *nom,char * espe,int colegiado,int trabajo);
                Medico(const Medico &m);
                Medico &operator=(const Medico &c);
                void operator delete(void*);
                ~Medico();
 };
 ostream& operator<<(ostream &o, Medico &c);
 ofstream& operator<<(ofstream &fichero, Medico &m);
 ifstream& operator>>(ifstream &fichero, Medico &m);

【问题讨论】:

  • #include 滥用是怎么回事?
  • 请重新格式化您的代码,删除所有不必要的垂直空格
  • 为什么不使用 std::string 而不是 char*? strcpy 也存在潜在的安全风险,因为它不检查数组边界。
  • 是的,问题是因为我使用 windows gcc 编译器进行编译,当我切换到 Ubuntu 并尝试编译时出现此错误,谢谢

标签: c++ deprecated


【解决方案1】:

观察:

  • #include &lt;cstring&gt; 应该引入 std::strcpy()。
  • using namespace std;(如 medico.h 中所写)将来自 std:: 的任何标识符引入到全局命名空间中。

除了using namespace std; 在应用程序变大时会有点笨拙(因为它在全局命名空间中引入了一大堆标识符),而且您应该永远不要在其中使用using一个头文件(见下文!),using namespace 不影响在声明之后引入的标识符

using namespace std 写在 header 中,包含在 medico.cpp 中,但#include &lt;cstring&gt; 出现在 之后。)

我的建议:using namespace std;(如果您坚持使用它)放入medico.cpp,在任何包含之后,并使用显式std::在 medico.h 中。


strcmpi() 根本不是标准函数;在 Windows 上定义时,您必须在 Linux 上以不同的方式解决不区分大小写的比较。

(一般而言,我想指出 this answer 以 C 和 C++ 中的“正确”字符串处理,因为每个应用程序都应该考虑到 Unicode。总结:标准 不能 em> 正确处理这些事情;使用ICU。)


warning: deprecated conversion from string constant to ‘char*’

“字符串常量”是指您在代码中编写字符串文字(例如"Hello")。它的类型是const char[],即常量字符数组(因为你不能改变字符)。您可以将数组分配给指针,但分配给 char *,即删除 const 限定符,会生成您看到的警告。


OT 澄清:头文件中的using 更改了包括该头在内的任何人的标识符的可见性,这通常不是头文件的用户想要的。例如,我可以在我的代码中完美地使用std::string 和自己编写的::string除非我包含你的 medico.h,因为这样两个类就会发生冲突。

不要在头文件中使用using

即使在实现文件中,它也会引入很多歧义。在实现文件中也可以使用显式命名空间。

【讨论】:

  • 谢谢你,我想解决错误的问题:'strcmpi' 没有在这个范围内声明我收到另一个警告:警告:不推荐从字符串常量到'char*'的转换
  • 抱歉,没有看到其他两种警告类型。我通常在重新编译之前只修复第一个错误,因为很多后续的错误/警告通常是后续问题,一旦最重要的问题得到解决,就会消失。我扩展了我的答案以涵盖其他两种情况。
  • " 完全不确定 using namespace 是否会影响语句后引入的标识符。" - 它影响语句后引入的标识符。这意味着如果以后使用了不合格的标识符,则将在namespace std 中搜索该标识符。 (听起来好像您将其视为“将std导入全局”之类的东西,这不是它的工作原理)。
【解决方案2】:

当你说:

 #include <cstring>

g++ 编译器应将其自身包含的&lt;string.h&gt; 声明放入std:: 和全局命名空间中。出于某种原因,它看起来好像没有这样做。尝试用std::strcpy 替换strcpy 的一个实例,看看是否能解决问题。

【讨论】:

  • 不正确。 &lt;cstring&gt;确实将声明放入std::,但是否也将它们放入全局命名空间取决于实现。我不确定该标准是否允许将它们放到全球范围内,但我很肯定它不需要要求它。
  • 它确实允许它,目前不需要它,我所说的行为是g ++的行为。在我的安装(4.4.1 版)上,它按照我说的做。
  • 抱歉,在语言标准方面我有点固执己见。 ;-)
【解决方案3】:

这个错误有时会出现在这样的情况下:

#ifndef NAN
#include <stdlib.h>
#define NAN (strtod("NAN",NULL))
#endif

static void init_random(uint32_t initseed=0)
{
    if (initseed==0)
    {
        struct timeval tv;
        gettimeofday(&tv, NULL);
        seed=(uint32_t) (4223517*getpid()*tv.tv_sec*tv.tv_usec);
    }
    else
        seed=initseed;
#if !defined(CYGWIN) && !defined(__INTERIX)
    //seed=42
    //SG_SPRINT("initializing random number generator with %d (seed size %d)\n", seed, RNG_SEED_SIZE)
    initstate(seed, CMath::rand_state, RNG_SEED_SIZE);
#endif
}

如果以下代码行没有在运行时运行:

#ifndef NAN
#include <stdlib.h>
#define NAN (strtod("NAN",NULL))
#endif

您将在代码中遇到如下错误;因为 initstate 放在 stdlib.h 文件中,而它没有被包含

In file included from ../../shogun/features/SubsetStack.h:14:0, 
                 from ../../shogun/features/Features.h:21, 
                 from ../../shogun/ui/SGInterface.h:7, 
                 from MatlabInterface.h:15, 
                 from matlabInterface.cpp:7: 
../../shogun/mathematics/Math.h: In static member function 'static void shogun::CMath::init_random(uint32_t)': 
../../shogun/mathematics/Math.h:459:52: error: 'initstate' was not declared in this scope

【讨论】:

    猜你喜欢
    • 2012-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-10
    • 2015-06-23
    • 2010-10-02
    相关资源
    最近更新 更多