2016-11-05 128 views
-3

我有这样的代码:C - fscanf可以使用字符指针,但不能使用双字符指针?

#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 s更改为string,它就会起作用。为什么是这样?我怎样才能使用指针数组fscanf?

谢谢。

+0

简答:你使用的是malloc错误 – Isaiah

+0

你想要一个字符串数组吗?像'string [0]'是一个字符串,'string [0] [0]'是一个char?你需要为数组char **做一个malloc,然后为每个字符串char *。 – cpatricio

+0

哎呀。谢谢。 – Pen275

回答

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]); 
} 
+0

啊,我明白了,谢谢。我认为分配双指针就和单指针一样。我使用fscanf的原因是,在我的实际应用程序(上面的代码只是测试我的错误),我同时扫描到三个不同的双指针。 – Pen275

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个字符串的阵列(然后将需要在循环中正确初始化)...

此外,未指定字符串的最大大小是容易出现缓冲区溢出错误,所以值得查看的限制,返回值和类似的东西也是如此。

0

此解决方案适用于字符串数组,也可以在每次我们要向数组中添加另一个字符串时执行realloc。

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