我正在嘗試決議格式如下的文本檔案:
XB0136;4310136;28;10
XB0136;4310136;29;C
XB0139;4310188;30;5
XB0145;4254875;31;20
如您所見,有一個模式,每一行對應于一些與序列號相關的值(第一個值由";"
我想搜索某個序列號并取對應的資料(序列號可以在我的檔案中重復,你可以看到前兩個相同但對應的資料不匹配:我想取兩個資料)
我的嘗試是打開檔案,將所有內容傳遞到陣列中,然后將陣列標記"\n"為第一個分隔符和";"第二個分隔符。
int main()
{
char matricola[50];
printf("insert serial number: \n");
scanf("%s", matricola);
FILE *fp=fopen("prova.txt","r");
if (!fp){
printf("file doesnt exist\n");
return -1;
}
fseek(fp, 0, SEEK_END);
unsigned int size=(ftell(fp));
rewind(fp);
if(size==-1){
printf("file is empty\n");
return -1;
}
if(size!=0) // if file not empty
{
printf("file exists and it is %u bytes\n", size);
char *delim = "\n", *delim2 = ";";
char buffer[size];
int rows = 25 // approx
int lines = ((size*sizeof(char)/rows) 100); // approx
char matrice[lines][rows];
fread(buffer,sizeof(buffer),1,fp);
fclose(fp);
char *svptr1, *svptr2;
char *token = strtok_r(buffer, delim, &svptr1);
int k=0;
while (token!=NULL)
{
strcpy(matrice[k],token);
token = strtok_r(NULL, delim, &svptr1);
k ;
}
}
return 1;
}
在這里,我設法擁有一個陣列陣列,其中每個索引都是我的 txt 檔案的一行。但是從這里我真的不知道該怎么做,我再次嘗試使用 strtok 但我的行為很奇怪。我想檢查每一行,看看序列號是否是我正在搜索的序列號,如果是,則將相應的資料保存在其他地方。然后轉到下一行。
uj5u.com熱心網友回復:
fgets可用于讀取檔案的每一行。
用于strncmp將行的第一個字符與序列號進行比較。strncmp將回傳0比賽。
匹配后,sscanf可以從行中決議欄位。掃描集[^;];將掃描最多 19 個不是分號的字符,然后掃描分號。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main ( void)
{
char matricola[50] = "";
char line[100] = "";
printf("insert serial number: \n");
fgets ( matricola, sizeof matricola, stdin);
size_t length = strcspn ( matricola, "\n");
matricola[length] = 0; // remove newline
FILE *fp=fopen("prova.txt","r");
if (!fp){
printf("file doesnt exist\n");
return -1;
}
char (*matrice)[4][20] = NULL;
size_t rows = 0;
while ( fgets ( line, sizeof line, fp)) {
if ( ! strncmp ( line, matricola, length)) {
char (*temp)[4][20] = NULL;
if ( NULL == ( temp = realloc ( matrice, sizeof *matrice * ( rows 1)))) {
fprintf ( stderr, "realloc problem\n");
free ( matrice);
return 1;
}
matrice = temp;
if ( 4 == sscanf ( line, "[^;];[^;];[^;];[^\n]"
, matrice[rows][0]
, matrice[rows][1]
, matrice[rows][2]
, matrice[rows][3])) {
rows;
}
}
}
for ( size_t each = 0; each < rows; each) {
printf ( "%s\n", matrice[each][0]);
printf ( "%s\n", matrice[each][1]);
printf ( "%s\n", matrice[each][2]);
printf ( "%s\n\n", matrice[each][3]);
}
free ( matrice);
return 0;
}
uj5u.com熱心網友回復:
https://en.cppreference.com/w/c/string/byte/strtok:
這個函式是破壞性的:它在字串 str 的元素中寫入 '\0' 字符。特別是,字串文字不能用作 strtok 的第一個引數。
我敢肯定,只要使用fscanf.
另一方面,這是一個分號分隔的值檔案,確實有很多庫可以可靠地讀取。不要對自己這樣做——C 對于字串處理來說真的不是一個很好(或安全使用)的語言,而且內置的實用程式strtok真的不是那么好(它們也有 50 年的歷史了!)。許多人在必須執行繁重的文本處理任務時會自動切換到 C 以外的其他語言,因為老實說,與其他語言相比,C 并沒有很好地完成這一特定任務!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/495201.html
下一篇:CSV的列串列結構
