【问题标题】:C - fscanf works with characters pointers but not double character pointers?C - fscanf 适用于字符指针但不适用于双字符指针?
【发布时间】:2016-11-05 03:58:36
【问题描述】:

我有这个代码:

#include<stdio.h>
#include<stdlib.h>

int main(void)
{
    char **string = malloc(sizeof(char) * 20);
    FILE *fp = fopen("input.txt", "r");
    fscanf(fp, "%s", *string); 

    printf("%s\n", *string);

}

此代码生成分段错误。但是,如果我将 **string 更改为单个字符指针并将 *strings 更改为 string 它可以工作。为什么是这样?以及如何将 fscanf 与指针数组一起使用?

谢谢。

【问题讨论】:

  • 简答:你使用 malloc 错误
  • 你想要一个字符串数组吗?就像string[0] 是一个字符串,而string[0][0] 是一个字符?您需要为数组 char** 做一个 malloc,然后为每个字符串 char* 做一个 malloc。
  • 明白了。谢谢。

标签: c pointers scanf


【解决方案1】:
char **string = malloc(sizeof(char*)); // Pointer to pointer --> Alloc size of a POINTER
*string = malloc(sizeof(char) * 20); // Dereference and then you can malloc chars

当你为一个指针分配一个指针时,你首先分配指针的大小。然后您取消引用变量并分配指针内容的大小,在本例中为它指向的字符数。

此外,您对fscanf 的使用不仅不安全,而且完全没有必要。

改用fgets:

fgets( *string, 20, fp );

如果你想分配一个指向 chars 的指针数组,那么在分配指向指针的指针时,将 sizeof char* 乘以条目数。您还必须使用 for 循环为每个字符指针分配内存,如上所示。

// Example code
char **string = malloc(sizeof(char*) * 10); // Allocates an array of 10 character pointers
if (string == 0) {
  fprintf(stderr, "Memory allocation failed.");
  exit(1);
}
int i = 0;
FILE *fp = fopen("input.txt", "r");
if (fp == 0) {
  fprintf(stderr, "Couldn't open input.txt for reading.");
  exit(1);
}
for (; i < 10; ++i) {
  string[i] = malloc(sizeof(char) * 20); // For each char pointer, allocates enough memory for 20 characters
  if (string[i] == 0) {
    fprintf(stderr, "Memory allocation failed.");
    exit(1);
  }
  fgets(string[i], 20, fp);
  printf("%s\n", string[i]);
}

【讨论】:

  • 啊,我明白了,谢谢。我假设分配双指针与单指针相同。我使用 fscanf 的原因是在我的实际应用程序中(上面的代码只是测试我的错误)我同时扫描到三个不同的双指针。
【解决方案2】:

使用简单的char *指针代替双指针:

char *string = malloc(sizeof(char) * 20);
FILE *fp = fopen("input.txt", "r");
fscanf(fp, "%s", string); 

printf("%s\n", string);

双指针是指向一个字符串(或字符串数​​组)的指针,并且第一个指针在原始代码中的任何地方都没有初始化。此外,第一个 malloc 必须看起来像 malloc(sizeof(char *)*20) - 这将提供 20 个字符串的数组(然后需要在循环中正确初始化)...

此外,不指定字符串的最大大小很容易出现缓冲区溢出错误,因此值得查看限制、返回值和类似的东西。

【讨论】:

    【解决方案3】:

    此解决方案适用于字符串数组,也可以在每次我们想向数组中添加另一个字符串时进行重新分配。

    #include<stdio.h>
    #include<stdlib.h>
    
    int main(void)
    {
        char **string = (char**)malloc(sizeof(char*) * 2); // array with 2 strings
    
        string[0] = (char*)malloc(sizeof(char)*20);
        FILE *fp = fopen("input.txt", "r");
        fscanf(fp, "%s", string[0]);
        fclose(fp); // Remember to close after you don't need file handle anymore
        printf("%s\n", string[1]);
    
        string[1] = (char*)malloc(sizeof(char)*20);
        FILE *fp2 = fopen("input2.txt", "r");
        fscanf(fp2, "%s", string[1]); 
        fclose(fp2);
        printf("%s\n", string[1]);
    
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 2020-10-24
      • 2016-12-29
      • 1970-01-01
      • 2013-11-06
      • 2020-07-26
      • 2020-09-11
      • 1970-01-01
      • 2023-04-06
      • 1970-01-01
      相关资源
      最近更新 更多