C上的字符串行为

时间:2014-07-23 04:19:05

标签: c string scanf

我想了解C上字符串的一些内容:

我无法理解为什么你不能在正常的作业中改变字符串。 (但只能通过string.h的函数),例如:我不能d="aa"(d是char的指针或char数组)。 有人可以向我解释幕后发生了什么 - 编译器会运行这样的事情而你会收到分段错误错误。

其他的,我在C中运行一个包含以下行的程序:

char c='a',*pc=&c;
printf("Enter a string:");
scanf("%s",pc);
printf("your first char is: %c",c);
printf("your string is: %s",pc);
  1. 如果我输入2个以上的字母(在scanf上)我会出现分段错误错误,为什么会这样?
  2. 如果我放两个字母,第一个字母就是正确的!字符串印有很多利润(不正确)
  3. 如果我写了一封信,那封信就是正确的!并且字符串印有很多利润,最后是一些奇怪的东西(一个有四个数字的正方形,包含零和一个)
  4. 任何人都可以解释背后发生的事情吗?

    请注意: 我不希望程序正常运行,我没有问这个问题来获取其他程序的建议,我只想了解在这些情况下幕后发生的事情。

3 个答案:

答案 0 :(得分:2)

C中几乎不存在字符串(除了像某些C源文件中的"abc"这样的C字符串文字)。

实际上,字符串主要是约定:C字符串是char的数组,其最后一个元素是零字符'\0'

如此声明

 const char s[] = "abc";

完全相同
 const char s[] = {'a','b','c','\0'};
特别是,sizeof(s)在两种情况下都是4(3 + 1)(因此sizeof("abc"))。

标准C库包含许多函数(例如strlen(3)strncpy(3) ...),这些函数遵循和/或预先假定字符串是{{1}的零终止数组的约定} -s

更好的代码是:

char

一些评论:害怕buffer overflow。读取字符串时,总是给读取字符串绑定,或者使用getline(3)之类的函数,dynamically allocates堆中的字符串。谨防memory leaks(使用像valgrind这样的工具......)

计算字符串时,也要注意最大尺寸。请参阅snprintf(3)(避免char buf[16]="a",*pc= buf; printf("Enter a string:"); fflush(NULL); scanf("%15s",pc); printf("your first char is: %c",buf[0]); printf("your string is: %s",pc); )。

通常,您采用的惯例是返回一个字符串并在堆中动态分配。如果您的系统提供,您可能需要使用strdup(3)asprintf(3)。但是你应该采用调用函数(或其他东西,但在你脑中定义得很好)的约定free(3) - 字符串。

你的程序在语义上可能是错误的,并且运气不好发生在有时的工作中。仔细阅读undefined behavior。绝对避免它(你的点1,2,3可能是UB)。可悲的是,UB有时可能会“工作”。

为了解释一些实际的未定义行为,你必须考虑你的特定实现:编译器,标志 - 特别是优化标志 - 传递给编译器,操作系统,内核,处理器,月相等等......未定义的行为通常不可重现(例如因为ASLR等...),请阅读heisenbugs。要解释第1,2,3点的行为,您需要深入了解实施细节;查看编译器生成的汇编代码(sprintf)。

我建议你使用所有警告和调试信息编译你的代码(例如使用gcc -S -fverbose-asmGCC ...),改进代码,直到你没有警告,并学习如何使用调试器(例如gcc -Wall -g)逐步运行代码。

答案 1 :(得分:1)

如果我输入2个以上的字母(在scanf上)我会出现分段错误错误,为什么会这样?

因为内存仅分配给一个字节。 请参阅char c并指定"a"。等于'a''\0'写入一个字节的内存位置。

如果scanf()使用此内存来读取多个字节,那么这只是未定义的行为

答案 2 :(得分:0)

char c="a";是c语言中的错误声明,因为即使单个字符包含在一对双引号("")中也会被视为C中的字符串,因为它被视为&#34;一个\ 0&#34;因为所有字符串都以&#39; \ 0&#39;空字符。 <{1}}是错误的,因为char c="a";是正确的。

另请注意,为char分配的内存仅为1byte,因此它只能容纳一个字符,数据类型的内存分配详细信息如下所述

 Operator Types