C fgets 和 getline 跳过来自标准输入的输入
C fgets and getline skip input from stdin
我在使用 getline/fgets 时遇到问题。我正在尝试从 stdin 中读取数据,同时通过管道传输文件中的输入,然后对其进行处理。虽然它在 opensuse 上与 gcc 4.8.5 一起工作得很好,但它不适用于带有 gcc 7 的 Arch Linux 和带有 gcc 5 的最新 ubuntu。后者将简单地跳过几行输入。 (我正在传输相同的文件)。在这个例子中,我的程序在通过管道输入时会跳过第三行和第四行,但在手动输入时不会。与更大的文件相同,只是总是跳过相同的行。有什么想法吗?非常感激。谢谢。
输入格式(每行后跟一个换行符):
0 1 2
2 3 4
3 4 5
2 4 5
1 2 3
1
2
3
我的代码如下所示:
int main(int argc, char *argv[]) {
int bytes;
size_t nbytes = 100;
char *str = (char *) malloc(nbytes+1); // 1 byte for [=11=]
long i = 0;
node *itemArray = malloc(sizeof(itemArray));
while ((bytes = getline(&str, &nbytes, stdin) != -1)) {
char* token;
char *rest = str;
int callNums = 0;
long from = 0;
long to = 0;
long weight = 0;
while((token = strtok_r(rest, " ", &rest))) {
if(callNums == 0) {
from = atol(token);
}
if(callNums == 1) to = atol(token);
if(callNums == 2) weight = atol(token);
callNums++;
}
if(callNums == 3) {
if(i == 0) {
itemArray[i].from = from;
itemArray[i].to = to;
itemArray[i].weight = weight;
printf("%li %li %li \n", itemArray[i].from, itemArray[i].to, itemArray[i].weight);
}
if(i > 0) {
node *tmp = realloc(itemArray, (i * sizeof(itemArray)));
if(tmp) {
itemArray = tmp;
itemArray[i].from = from;
itemArray[i].to = to;
itemArray[i].weight = weight;
printf("%li %li %li \n", itemArray[i].from, itemArray[i].to, itemArray[i].weight);
}
else { printf("realloc failed");
exit(-1); }
}
++i;
}
}
}
free(str);
free(itemArray);
return(0);
}
试一试。通过将 itemArray 设置为 NULL,对 realloc 的第一次调用将像 malloc 一样工作。将 str 设置为 NULL 并将 nbytes 设置为 0 应该可以正常使用 getline。
sscanf 应该可以从字符串中扫描三个 long。如果成功扫描了三个,它们将被添加到 itemarray。
int main( int argc, char *argv[]) {
int bytes;
size_t nbytes = 0;
char *str = NULL;
long i = 0;
node *itemArray = NULL;
while ( ( bytes = getline ( &str, &nbytes, stdin) != -1)) {
int callNums = 0;
long from = 0;
long to = 0;
long weight = 0;
if ( 3 == sscanf ( str, "%ld%ld%ld", &from, &to, &weight)) {
node *tmp = realloc ( itemArray, ( ( i + 1) * sizeof ( *tmp)));
if(tmp) {
itemArray = tmp;
itemArray[i].from = from;
itemArray[i].to = to;
itemArray[i].weight = weight;
printf ( "%li %li %li \n", itemArray[i].from, itemArray[i].to, itemArray[i].weight);
}
else {
printf("realloc failed");
exit(-1);
}
++i;
}
}
free(str);
free(itemArray);
return(0);
}
我在使用 getline/fgets 时遇到问题。我正在尝试从 stdin 中读取数据,同时通过管道传输文件中的输入,然后对其进行处理。虽然它在 opensuse 上与 gcc 4.8.5 一起工作得很好,但它不适用于带有 gcc 7 的 Arch Linux 和带有 gcc 5 的最新 ubuntu。后者将简单地跳过几行输入。 (我正在传输相同的文件)。在这个例子中,我的程序在通过管道输入时会跳过第三行和第四行,但在手动输入时不会。与更大的文件相同,只是总是跳过相同的行。有什么想法吗?非常感激。谢谢。
输入格式(每行后跟一个换行符):
0 1 2
2 3 4
3 4 5
2 4 5
1 2 3
1
2
3
我的代码如下所示:
int main(int argc, char *argv[]) {
int bytes;
size_t nbytes = 100;
char *str = (char *) malloc(nbytes+1); // 1 byte for [=11=]
long i = 0;
node *itemArray = malloc(sizeof(itemArray));
while ((bytes = getline(&str, &nbytes, stdin) != -1)) {
char* token;
char *rest = str;
int callNums = 0;
long from = 0;
long to = 0;
long weight = 0;
while((token = strtok_r(rest, " ", &rest))) {
if(callNums == 0) {
from = atol(token);
}
if(callNums == 1) to = atol(token);
if(callNums == 2) weight = atol(token);
callNums++;
}
if(callNums == 3) {
if(i == 0) {
itemArray[i].from = from;
itemArray[i].to = to;
itemArray[i].weight = weight;
printf("%li %li %li \n", itemArray[i].from, itemArray[i].to, itemArray[i].weight);
}
if(i > 0) {
node *tmp = realloc(itemArray, (i * sizeof(itemArray)));
if(tmp) {
itemArray = tmp;
itemArray[i].from = from;
itemArray[i].to = to;
itemArray[i].weight = weight;
printf("%li %li %li \n", itemArray[i].from, itemArray[i].to, itemArray[i].weight);
}
else { printf("realloc failed");
exit(-1); }
}
++i;
}
}
}
free(str);
free(itemArray);
return(0);
}
试一试。通过将 itemArray 设置为 NULL,对 realloc 的第一次调用将像 malloc 一样工作。将 str 设置为 NULL 并将 nbytes 设置为 0 应该可以正常使用 getline。
sscanf 应该可以从字符串中扫描三个 long。如果成功扫描了三个,它们将被添加到 itemarray。
int main( int argc, char *argv[]) {
int bytes;
size_t nbytes = 0;
char *str = NULL;
long i = 0;
node *itemArray = NULL;
while ( ( bytes = getline ( &str, &nbytes, stdin) != -1)) {
int callNums = 0;
long from = 0;
long to = 0;
long weight = 0;
if ( 3 == sscanf ( str, "%ld%ld%ld", &from, &to, &weight)) {
node *tmp = realloc ( itemArray, ( ( i + 1) * sizeof ( *tmp)));
if(tmp) {
itemArray = tmp;
itemArray[i].from = from;
itemArray[i].to = to;
itemArray[i].weight = weight;
printf ( "%li %li %li \n", itemArray[i].from, itemArray[i].to, itemArray[i].weight);
}
else {
printf("realloc failed");
exit(-1);
}
++i;
}
}
free(str);
free(itemArray);
return(0);
}