[英]How to read only integers from a file with strings, spaces, new lines and integers in C
我知道這是一個非常瑣碎的問題,但我只需要快速幫助。 我已經嘗試了一段時間了。 我要做的就是從具有以下形式的文本文件中讀取整數:
8 blah blah
10 blah blah
2 blah blah
3 blah blah
我最終只想取數字,將它們存儲在數組中,然后將這些數字放入BST中。 當我的文件只有數字而不是指定的文件格式時,我的BST可以正常工作。
不要緊,什么blah
是我只是想獲得的號碼,並將其存儲在數組中。 如果我拿出blah's
我可以做到blah's
。 使用fscanf
,我得到了存儲第一個數字8
,但是它在那里停止了。 同樣在此示例中,有四行,但是文件中有多少行都沒有關系。 可能是12或6。如何正確執行此操作。 以下是我為解決此問題所做的嘗試。
fscanf(instructionFile, "%d", &num);
我也嘗試做類似的事情
while(!feof(instructionFile)){
fscanf("%d %s %s", &num, string1, string2);
}
要存儲所有內容,只能使用整數,但是當我執行此類操作時,我的BST無法正常工作。
使用fgets()
獲取一行輸入,並使用sscanf()
獲取整數。 在使用fscanf()
的示例中,第一個調用將讀取一個int
,而下一個調用將失敗,因為輸入流中的下一個項目不是int
。 每次失敗后,錯誤的輸入都會留在輸入流中。 通過一次獲取一行,您可以在獲取另一行輸入之前隨意掃描該行。
這是您可能如何執行此操作的示例。 並請注意,您不應使用feof()
來控制讀取循環; 而是使用fgets()
的返回值。 此代碼假定一行上的第一個條目是您想要的數據,可能帶有前導空格。 可以為稍微復雜一些的情況修改格式字符串。 如果需要更好地控制行的解析,也可以使用strtok()
。
#include <stdio.h>
#include <stdlib.h>
#define MAX_LINES 100
int main(void)
{
FILE *fp = fopen("data.txt", "r");
if (fp == NULL) {
fprintf(stderr, "Unable to open file\n");
exit(EXIT_FAILURE);
}
char buffer[1000];
int arr[MAX_LINES];
size_t line = 0;
while ((fgets(buffer, sizeof buffer, fp) != NULL)) {
if (sscanf(buffer, "%d", &arr[line]) != 1) {
fprintf(stderr, "Line formatting error\n");
exit(EXIT_FAILURE);
}
++line;
}
for (size_t i = 0; i < line; i++) {
printf("%5d\n", arr[i]);
}
fclose(fp);
return 0;
}
最好在調用sscanf()
之前添加對空行的檢查; 現在,空行被認為是格式錯誤的數據。
示例文件的輸出:
8
10
2
3
如果您只想從一堆文件中挑選整數,那么實際上您需要遍歷讀取的每一行,並用一個指針來標識每個起始數字(或起始-
負數的符號),一次轉換找到的每個整數。 您可以使用指針和sscanf
來執行此操作,也可以使用strtol
來執行此操作,並利用endptr
參數在成功轉換后移至下一個字符。 如果願意,您還可以使用面向字符的輸入(例如getchar
或fgetc
)手動執行數字識別和轉換。
從fgets
和sscanf
方法開始,接下來的內容將繼續。 不管您使用sscanf
還是strtol
,整個鍵都是使下一個讀取的開始前進到找到的每個整數之后的字符,例如
#include <stdio.h>
#include <stdlib.h>
#define MAXC 256
int main (int argc, char **argv) {
char buf[MAXC] = ""; /* buffer to hold MAXC chars at a time */
int nval = 0; /* total number of integers found */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading */
fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
return 1;
}
while (fgets (buf, MAXC, fp)) {
char *p = buf; /* pointer to line */
int val, /* int val parsed */
nchars = 0; /* number of chars read */
/* while chars remain in buf and a valid conversion to int takes place
* output the integer found and update p to point to the start of the
* next digit.
*/
while (*p) {
if (sscanf (p, "%d%n", &val, &nchars) == 1) {
printf (" %d", val);
if (++nval % 10 == 0) /* output 10 int per line */
putchar ('\n');
}
p += nchars; /* move p nchars forward in buf */
/* find next number in buf */
for (; *p; p++) {
if (*p >= '0' && *p <= '9') /* positive value */
break;
if (*p == '-' && *(p+1) >= '0' && *(p+1) <= '9') /* negative */
break;
}
}
}
printf ("\n %d integers found.\n", nval);
if (fp != stdin) fclose (fp); /* close file if not stdin */
return 0;
}
輸入示例
以下兩個輸入文件說明了從混合輸入中僅選擇整數。 您的檔案:
$ cat dat/blah.txt
8 blah blah
10 blah blah
2 blah blah
3 blah blah
一個非常凌亂的文件
$ cat ../dat/10intmess.txt
8572,;a -2213,;--a 6434,;
a- 16330,;a
- The Quick
Brown%3034 Fox
12346Jumps Over
A
4855,;*;Lazy 16985/,;a
Dog.
11250
1495
使用/輸出示例
在您的情況下:
$ ./bin/fgets_sscanf_int_any_ex < dat/blah.txt
8 10 2 3
4 integers found.
使用真正凌亂的文件:
$ ./bin/fgets_sscanf_int_any_ex <dat/10intmess.txt
8572 -2213 6434 16330 3034 12346 4855 16985 11250 1495
10 integers found.
仔細看一下,如果您有任何問題,請告訴我。
一種“只讀整數”的簡單方法是在失敗時使用fscanf(file_pointer, "%d", ...)
和fgetc()
int x;
int count;
while ((count = fscanf(file_pointer, "%d", &x)) != EOF) {
if (count == 1) {
// Use the `int` in some fashion (store them in an array)
printf("Success, an int was read %d\n", x);
} else {
fgetc(file_pointer); // Quietly consume 1 non-numeric character
}
}
我得到了存儲第一個數字8的代碼,但它在那里停止了。
那是因為有問題的非數字輸入保留在FILE流中。 該文本需要以其他方式使用。 調用fscanf(instructionFile, "%d", &num);
再次簡單地得出相同的問題: fscanf()
失敗,因為初始輸入為非數字。
注意:OP的代碼缺少FILE指針
// fscanf(????, "%d %s %s", &num, string1, string2);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.