C - fscanf适用于字符指针而不是双字符指针吗?

时间:2016-11-05 03:58:36

标签: c pointers scanf

我有这段代码:

#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更改为单个字符指针并将*string更改为string则可行。为什么是这样?如何将fscanf与指针数组一起使用?

感谢。

3 个答案:

答案 0 :(得分:2)

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 );

如果要为字符分配指针数组,则在分配指针指针时,将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]);
}

答案 1 :(得分:0)

使用简单的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个字符串的数组(然后需要在循环中正确初始化)...

另外,不指定字符串的最大大小容易出现缓冲区溢出错误,因此值得查看限制,返回值等等。

答案 2 :(得分:0)

此解决方案适用于字符串数组,每次我们要将另一个字符串添加到数组时,也可以执行重新分配。

#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;
}