C 从字符串中打印一个字符

C 从字符串中打印一个字符,c,arrays,string,memory-management,io,C,Arrays,String,Memory Management,Io,我面临着一个与在c中从字符串打印一个字符有关的问题。 该函数从用户那里获取两个变量:number(从字符串中打印字符的数字)和string。当我输入一个字符串“Martin”并且数字是5,那么输出是“I”。但是,当数字大于字符串长度时,出现了一些问题,我实际上不知道出了什么问题 注:如果数字大于字符串大小,则应打印“无” 这里不需要动态分配,因为您事先不知道字符串的长度,所以只需执行以下操作: void printLetter() { char string[100]; // examp

我面临着一个与在c中从字符串打印一个字符有关的问题。 该函数从用户那里获取两个变量:number(从字符串中打印字符的数字)和string。当我输入一个字符串“Martin”并且数字是5,那么输出是“I”。但是,当数字大于字符串长度时,出现了一些问题,我实际上不知道出了什么问题

注:如果数字大于字符串大小,则应打印“无”


这里不需要动态分配,因为您事先不知道字符串的长度,所以只需执行以下操作:

void printLetter() {
    char string[100]; // example size 100
    ...
    scanf("%99s", string); // read no more than your array can hold
}
一个有趣的练习是计算字符串的长度,根据需要动态地分配大量空间(+1表示空终止符),将
string
复制到动态分配的空间中,根据需要使用它,然后释放它


此外,这:

printf("%c\n", string[n+1]);
应这样写:

printf("%c\n", string[n-1]);
因为您不想超出数组的界限(并导致未定义的行为),或者在请求的字符旁边打印两个字符,因为当我请求第一个字符时,您应该打印
字符串[0]
,当我请求第二个字符时,您应该打印
字符串[1]
,依此类推。因此,当用户要求输入
n
-th字母时,您可以看到为什么我们需要打印
string[n-1]

顺便说一下,在处理索引时,通常使用名为
i
的变量,而不是像您这样使用
n
。)


在代码中,这是:

char * string = malloc(sizeof(char));
只为一个字符分配内存,这是不好的,因为即使字符串只有一个字母,您会将空终止符放在哪里?您知道C中的字符串应该(几乎)总是
NULL
终止

要为大小为
N
的字符串动态分配内存,应执行以下操作:

char * string = malloc((N + 1) * sizeof(char));
其中为
N
字符分配空间,为
NULL
终止符分配1。

两个问题

sizeof(char)通常为1字节。因此malloc()只为字符串分配一个字节的内存。也许需要更大的内存块?例如,“Martin”至少需要6个字节,加上字符串终止字符(总共7个字节)

printf(“%c\n”,字符串[n+1])可能不太正确

  String: Martin\0
  strlen= 6
  Offset: 0123456
  n = 5... [n+1] = 6
  The character being output is the string terminator '\0' at index 6.
这可能会更好:

  void printLetter() {

      char * string = malloc(100 * sizeof(char));
      int n;

      printf("Number:\n");
      scanf("%i", &n);
      printf("String:\n");
      scanf("%s", string);

      if(n > strlen(string)) {
          printf("nothing");
      } else {
          printf("%c\n", string[n-1]);
      }

   free(string);


  }

您正面临缓冲区溢出。 看看这个问题,它将向您展示如何在这种情况下正确管理内存:


或者,您可以询问字母的数量,并只分配那个么多的内存+1。然后
fgets(string,n,stdin)因为您不需要字符串的其余部分:-)

char*string=malloc(sizeof(char))
您正在为单个
字符分配空间
-因此,如果您尝试编写更多的字符(在
scanf(“%s”,string);
)您已经得到了未定义的行为,因此我应该这样分配:
char*string=malloc(100*sizeof(char))?@unholyseep
scanf(“%0s”,字符串)怎么样
scanf(“%*s”,字符串)string[0]='\0',则代码>是安全的首先被调用:)是的,您需要分配更多-100应该足够了。还要注意,在这个特定的代码中,实际上不需要使用
malloc
free
,只需声明
char
数组(例如:
char string[100];
)string[n+1]-->string[n-1]…另外,您只为字符串变量分配了1个字节。感谢您的努力。@BLUEPIXY我正准备用您所做的一切进行更新,您是一个天使。@gsamaras Better:)如果您可以声明char string[100];为什么要使用malloc?当字符串长度超过100个字符时会发生什么情况?@DevilaN,我会做很多事情来使代码达到我的标准。不幸的是,到那时,与问题代码几乎没有相似之处。我认为最好是进行最小的更改,以使代码能够运行,而不涉及scant()、缓冲区大小等问题。详细信息:“sizeof(char)通常是1字节。”在C中,它总是1字节,正如C定义的一个字节
  void printLetter() {

      char * string = malloc(100 * sizeof(char));
      int n;

      printf("Number:\n");
      scanf("%i", &n);
      printf("String:\n");
      scanf("%s", string);

      if(n > strlen(string)) {
          printf("nothing");
      } else {
          printf("%c\n", string[n-1]);
      }

   free(string);


  }