繁体   English   中英

将char转换为char数组或将char数组转换为char?

[英]Cast char to char array or char array to char?

所以,假设我有一个char,我想在一行代码中将它strcat()转换为char数组。 对于[非实际]示例:

strcat("ljsdflusdfg",getchar());

或者我想反过来说,无论数据类型如何,连接或类型转换字符串的适当功能是什么? 或者也许有一些我遗漏的语法......

这是一个例子。 它编译得很好,但崩溃。

char* input(){
 char* inp="";
 while(1){
  char c=getchar();
  if(c){
   if(c=='\n'||c==EOF){
    break;
   }else{
    strcat(inp,(char*)c);
   }
  }
 }
 return inp;
}

strcat将其参数视为指向以空字符结尾的字符串的指针。 把一个char变成一个char *是危险的,我可以想象没有理由它会有用(不要暗示你尝试它是愚蠢的 - 每个人在学习时都犯了愚蠢的错误。这就是为什么我们在这里。 )

原因是它会解释单字节char ,加上围绕该char的额外sizeof(char*) - sizeof(char) (通常为3)字节作为指针,指向......任何地方。 你无法知道它指向的位置,因为其中3个字节超出了你的控制范围,因此无法知道它是否指向有效数据。

您可以将此作为第二种方法:

strcat(inp, &c);

这一次,你会做得更好,因为&cchar *类型的表达式,不需要强制转换。 但同样, strcat假设它的参数是一个以空字符结尾的字符串,并且因为你无法在char数据之后保证一个空字节,所以这不行。

最好的方法是:

size_t len = strlen(inp); // this may already be calculated somewhere else
...
inp[len++] = c; // add c as the last character, and adjust our len
inp[len] = '\0'; // add a new nul terminator to our string

更新:

实际上,我撒了谎。 最好的方法是使用标准库函数fgets ,它似乎或多或少地做了你想要做的事情。 说实话我忘记了,但如果这是家庭作业,你的教授可能不会要你使用fgets这样你就可以学习如何手动完成。 但是,如果这不是家庭作业,那么fgets正是你正在寻找的。 (实际上,第三种方法正在重新实现fgetsfgets的功能。)

我还要在input函数上添加一些其他注释:

  1. char* inp = ""; 将指向只读数据。 C标准中的缺陷(用于向后兼容性)允许将字符串文字分配给char*类型而不是const char *类型,因为它(IMHO)应该是。

    有几种方法可以解决这个问题,但最好的方法是动态分配。 使用malloc函数保留一些数据,跟踪你在函数中使用了多少,并使用realloc函数,如果你最终需要更多空间来存储它。 如果你需要帮助,我相信你会回到这里(希望不会太早 )另一个问题。 :)
  2. getchar()返回一个int ,因为EOF被定义为超出char的正常范围。 为了区分任何charEOF ,最好将c设为int 否则,完全有效的角色可能会发出EOF信号。 但是,当您将c添加到字符串时,请务必将其转换为char
strcat(inp,(char*)c);

那就是尝试将内存的内容连接到“c”(作为内存位置),直到找到零为止。

更好的方法是创建一个空字符串,其中包含您认为合理的最大大小,用零填充,然后在当前最后位置插入'c'

如果你想串联一个char到串上,你可以用strncat()和指定的字符数来连接为1 但请注意:

  • 目标缓冲区必须有足够的空间;
  • 在C89中,你必须有一个实际的char对象来获取地址(所以你不能直接连接getchar()的结果。

例如:

char str[5] = "foo";
char c;
int ch;

if ((ch = getchar()) != EOF) {
    c = ch;
    strncat(str, &c, 1);
}

在C99中,您可以使用复合文字 ,第二个限制不适用:

char str[5] = "foo";
int ch;

if ((ch = getchar()) != EOF) {
    strncat(str, &(char){ ch }, 1);
}

这不起作用,因为* inp char指针没有任何内存备份它。 当你声明它是char * inp =“”;时,你只给它一个空字符串的地址。 如果您给出了以下声明char * inp =“abcdefg”,那么在覆盖'\\ 0'并遇到麻烦之前,您可以写入7个字符。

当您输入越来越多的字符时,您将需要动态增加后备内存的大小。 您还将遇到知道何时释放内存以避免内存泄漏的问题。

另外,你的strcat需要在c之前有'&'。

一种简单的方法是使用snprintf:

char newString[50+1];
snprintf(newString, sizeof(newString), "%s%c", "ljsdflusdfg", getchar());

这是一个简单的解决方案,但确实要求您大致知道字符串将提前有多大。

注意:我使用+1来提醒自己需要有空终止空间,并且snprintf优于sprintf,因为它被赋予缓冲区的大小以防止缓冲区溢出。

首先,您将返回指向堆栈分配数组的指针。 这是未定义的行为。 其次,您正在尝试将字符写入未分配的内存中。 第三, inp的类型是const char*而不是char*

你想要的东西:

char* input(char *dest) {
  strcpy(dest,"");
  while(1){
  char c=getchar();
  if(c){
   if(c=='\n'||c==EOF){
    break;
   }else{
    strcat(inp,&c);
   }
  }
 }
 return dest;
}

您的代码崩溃,因为strcat期望其两个参数都以空字符结尾的字符串。

如果要连接char,则需要首先从中创建以null结尾的字符串。

char c[2] = {0,0};
c[0] = getchar();
strcat(inp, c);

但是不要使用strcat ,除非你能保证输入字符串已为该额外字符分配了空间。 更好的strncat,它还包括第一个参数(dest)中空间量的参数。

我建议你阅读首。

将char转换为char数组?
这就像是说你想把一个字符串转换成字符串。
你不能直接这样做。
而不是char,将它放在一个数组(myChar [])中。
之后,用你原来的char数组来strcat它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM