[英]Why wont the integers print from a file in C
我用 C 編寫了一個簡單的程序來從文件中讀取整數,並將整數打印到stdout
。 代碼可以編譯,但不會打印出我在不同文件中編寫的整數。 這是我寫的:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
FILE *fp = fopen(argv[0], "r");
int x = 0;
int nums[1024];
int num;
while (fscanf(fp, "%d", &num) == 1) {
nums[x] = num;
x++;
}
printf("Here are your numbers");
int i = 0;
while (nums[i] != '\0') {
printf("%d\n", nums[i]);
i++;
}
fclose(fp);
exit(0);
}
我只是想打印用fp
寫的整數
你的代碼有很多問題。 首先是錯字: nums
已聲明,但變量是num
。
argv[0]
不是程序的第一個參數,它是程序的名稱(產生程序的execv
調用的第一個參數)。 程序的第一個參數是argv[1]
。 您必須檢查argv[1]
存在以及文件是否成功打開。
if( argc <= 1 ) {
fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
return -1;
}
FILE *fp = fopen(argv[1], "r");
if( fp == NULL ) {
fprintf(stderr, "Could not open %s for reading\n", argv[1]);
return -1;
}
然后是如何確定數組中有多少個數字的問題。 您使用的技術適用於以空字符結尾的字符串(字符數組)或指針數組,但對於整數數組nums[i] != '\\0'
與nums[i] != 0
你可能會讀到數字零。 所以你不能在整數數組上使用這種邊界技術。 (你也忘了在數字閱讀結束時設置邊界)
相反,您已經有x
跟蹤您讀入的數字數量。使用它。 我已將其重命名為更具描述性的num_nums
。 我還使用了for
循環來使帶有遞增計數器的循環更清晰。
int num_nums = 0;
int nums[1024];
int num;
for( num_nums = 0; fscanf(fp, "%d", &num) == 1; num_nums++ ) {
nums[num_nums] = num;
}
printf("Here are your numbers.\n");
for( int i = 0; i < num_nums; i++ ) {
printf("%d\n", nums[i]);
}
最后一個問題是使用固定大小的數組來處理輸入。 固定大小的緩沖區和輸入是一個等待發生的安全漏洞。 您應該將輸入限制為緩沖區的大小(即 1024 個數字),或者更好的是,使用自動增長的數組。 這種類型的數組通常是一個結構體,它也為您跟蹤其大小。
與其實施一個,我鼓勵您使用提供改進數據結構的眾多庫之一,例如Gnome Lib 。
首先, argv[0]
是程序名。 我想你的意思是argv[1]
,它是第一個命令行參數,不包括程序名稱。 然后,檢查fopen
的返回值。 如果為NULL
,則無法打開文件。 修改后的代碼是
int main(char *argv[], int argc)
{
FILE *fp;
int i;
if ((fp = fopen(argv[1], "r")) != NULL) {
while (fscanf(fp, "%d", &i) > 0)
printf("%d\n", i);
} else /* could not open file; print reason */
perror("fopen");
fclose(fp);
return 0;
}
除了@stackptr在他的回答中所說的......
while(nums[i] != '\0'){
不是循環從文件中讀取的數字的正確方法。 nums
的元素未初始化超出從磁盤讀取的內容。 因此,將它們的值與'\\0'
進行比較是導致未定義行為的原因。
您可以使用:
// x is the number of ints read into nums.
for ( i = 0; i < x; ++i )
{
printf("%d\n", nums[i]);
}
您正在嘗試使用argv[0]
讀取可執行文件本身。 雖然它沒有任何問題,但是文件的開頭與"%d"
說明符所期望的不匹配,因此循環將終止,因為您有一個條件,即它必須在每次迭代中讀取一個條目,直到無法讀取任何條目. 因此x
將是'\\0'
。
即使您使用了argv[1]
並傳入了一些包含例如1 2 3
文件,這也將是一場災難。 這是因為您正在從數組nums
打印,直到它的第i
個條目不是'\\0'
。 您從未將nums
設置為'\\0'
,並且nums
是一個自動(局部)變量。 因此,您的程序將具有未定義的行為。 要理解我在說什么,請嘗試將nums
所有元素初始化為5
,然后使用包含上述示例的文件運行程序。 因此將循環更改為while (i < x) { /* print your nums[i] and increment i */ }
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.