我正在尝试从文件中读取行并将它们存储在多维char指针中。当我运行我的代码时,它运行没有错误,但是,我的main()函数中的行不会正确打印,而是在getline()函数中正确打印。任何人都可以解释发生了什么,以及我如何正确地将它们存储在我的多维指针中?
我的代码:
int main (int argc, const char * argv[]) {
char **s = (char**) malloc(sizeof(char*) * 1000);
int i = 0;
while (getline(s[i]) != -1){
printf("In array: %s \n", s[i]);
i++;
}
return 0;
}
int getline(char *s){
s = malloc(sizeof(char*) * 1000);
int c, i = 0;
while ((c = getchar()) != '\n' && c != EOF) {
s[i++] = c;
}
s[i] = '\0';
printf("String: %s \n", s);
if (c == EOF) {
return -1;
}
return 0;
}
和我的输出:
String: First line
<br>In array: (null)
<br>String: Second line
<br>In array: (null)
<br>String: Third line
<br>In array: (null)
答案 0 :(得分:2)
你正在经历价值。即使您在*s
中更改getline()
的值,但主要不会看到它。您必须传递s[i]
的地址,以便getline()
可以更改它:
int getline(char **s) {
* s= malloc( sizeof(char) * 1000) ;
...
}
此外,如果您希望内存更高效,请根据需要将该行读入本地缓冲区(大小为1000)。然后,当您完成读取该行时,仅分配存储实际字符串所需的内存。
int getline( char ** s )
{
char tmpstr[1000] ;
...
tmpstr[i++]= c ;
}
tmpstr[i]= '\0' ;
* s= strdup( tmpstr) ;
return 0 ;
}
如果你想进一步改进,那就退后一步吧。 1)在两个不同的函数中分配多维数组的两个部分将使其他人更难理解。 2)从外部传递一个临时字符串到getline()
将使它变得更加简单:
int main()
{
char ** s= (char **) malloc( 1000 * sizeof(char *)) ;
char tmpstr[1000] ;
int i ;
while ( -1 != getline( tmpstr))
{
s[i ++]= strdup( tmpstr) ;
}
return 0 ;
}
int getline( char * s)
{
int c, i = 0 ;
while (( '\n' != ( c= getchar())) && ( EOF != c )) { s[i ++]= c ; }
s[i]= '\0' ;
return ( EOF == c ) ? -1 : 0 ;
}
现在,getline
只是关于IO,s
的所有分配都在一个地方处理,因此更容易推理。
答案 1 :(得分:1)
问题是getline
函数内的这一行
s = malloc(sizeof(char) * 1000); // Should be sizeof(char), not sizeof(char*)
对传入的s[i]
指针没有影响。这是因为指针是按值传递的。
你有两个选择:
main
,并继续传递指针,或getline
中,但将指针传递给指向main
的指针。以下是您为第一个选项更改main
的方式:
int main (int argc, const char * argv[]) {
char **s = malloc(sizeof(char*) * 1000);
int i = 0;
for ( ; ; ) {
s[i] = malloc(sizeof(char) * 1000);
if (getline(s[i]) == -1) break;
printf("In array: %s \n", s[i]);
i++;
}
return 0;
}
答案 2 :(得分:0)
为什么首先使用malloc。 malloc非常危险!!
只需使用s[1000][1000]
并传递&s[0][0]
作为第一行,&s[1][0]
作为第二行等。
打印printf("%s \n", s[i]);
,其中i是您想要的行。
答案 3 :(得分:0)
我的建议:完全避免编写自己的getline()
函数,并避免使用所有固定大小的缓冲区。在POSIX.1-2008标准中,已经有getline()
函数。所以你可以这样做:
//Tell stdio.h that we want POSIX.1-2008 functions
#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
int main() {
char** s = NULL;
int count = 0;
do {
count++;
s = realloc(s, count*sizeof(char*));
s[count-1] = NULL; //so that getline() will allocate the memory itself
} while(getline(&s[count-1], NULL, stdin));
for(int i = 0; i < count; i++) printf(s[i]);
}