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

时间:2011-01-14 03:01:37

标签: c string char c89 concat

所以,假设我有一个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;
}

8 个答案:

答案 0 :(得分:3)

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

原因是它会将单个字节charsizeof(char*) - sizeof(char)周围的额外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*类型而不是({1}}类型,因为它应该是(IMHO)。

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

答案 1 :(得分:2)

strcat(inp,(char*)c);

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

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

答案 2 :(得分:2)

如果您希望将单个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);
}

答案 3 :(得分:1)

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

当您输入越来越多的字符时,您将需要动态增加后备内存的大小。你也会遇到知道何时释放内存的问题,这样你就不会出现内存泄漏。

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

答案 4 :(得分:0)

首先,您将返回指向堆栈分配数组的指针。这是未定义的行为。其次,您正在尝试将字符写入未分配的内存中。第三,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;
}

答案 5 :(得分:0)

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

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

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

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

我建议先阅读this

答案 6 :(得分:0)

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

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

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

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

答案 7 :(得分:-1)

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