2014-04-24 150 views
0

這是一個相對簡單的事情,但我一直有問題將字符串從文件分離成多個變量。我用分隔符嘗試了strtok和sscanf,但我似乎做錯了什麼。C字符串解析

#define MAX 40 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <math.h> 

int main() 
{ 
    char brd_str[26]; 
    char board[26], Res[26], Ind[26], Cap[26]; 
    int i=0, n=0; 
    FILE *data; 

    data = fopen ("C:\\datafile.txt", "rt"); 
    fgets(brd_str, 26, data); 
    sscanf(brd_str,"%d[^,],%f[^,],%e[^,],%e[^,]", &board, &Res, &Ind, &Cap); 
    printf("%3d %6d %8e %8e", board, Res, Ind, Cap); 

    fclose(data); 
    printf("\nPlease enter something for the program to exit"); 
    scanf("%d", &i); 
    return(0); 
} 

字符串本身看起來像這樣2,4.57,2.01e-2,5.00e-8。在這種情況下逗號將成爲分隔符。當我編譯它時,我確實有很多不正確的數字。

這將不得不進行多次(最多40次),並且變量本身將用於計算。

我輸入的sscanf語句似乎有問題。我不確定問題出在哪裏。

+2

它可以幫助你調試代碼,如果你在fgets()後面打印出'brd_str'。也許它的內容不會是你所期望的? –

+0

我剛剛嘗試過它,它似乎正在顯示字符串,因爲它在文件上。 – user3569350

+0

所以'board'是一個字符串。看起來你正在嘗試sscanf()它與%d?也許你應該用%s來掃描它,然後用%s打印它? –

回答

0

變化:

char board[26], Res[26], Ind[26], Cap[26]; 

到:

int board; 
    float Res; 
    float Ind; 
    float Cap; 

而且,變化:

printf("%3d %6d %8e %8e", board, Res, Ind, Cap); 

來(也許):

printf("%3d %6f %8e %8e", board, Res, Ind, Cap); 
0

基本上,你的最直接的問題是

char board[26], Res[26], Ind[26], Cap[26]; 

所以,你有一個字符串...

sscanf(brd_str,"%d[^,],%f[^,],%e[^,],%e[^,]", &board, &Res, &Ind, &Cap); 

你不能"%e"讀入字符串(的地址)!

printf("%3d %6d %8e %8e", board, Res, Ind, Cap); 

你不能"%e"


打印字符串也有相當多的更多的問題與您的代碼。

0

只是爲編碼風格提示,看看下面的代碼...

#include <stdio.h> 
#include <stdlib.h> 

int main(int argc, char **argv) 
{ 
FILE *file; 
int c, cp; 
char *buf = (char*)malloc(sizeof(char) * 100); 

for (c = 0; c < 100; c++) 
{ 
    buf[c] = 0; 
} 

file = fopen("input.txt", "r"); 

cp = 0; 
while((c = fgetc(file)) != EOF) 
{ 
    if (c != ',') 
    { 
     buf[cp] = (int)c; 
     cp++; 
    } 
    printf("%c", c); 
} 

for (c = 0; c < 100; c++) 
{ 
    printf("Buf%d: %c\n", c, buf[c]); 
} 

free(buf); 

return 0; 
} 

此代碼從文件中加載字符。如果你想要的字符串,考慮簡單的字符串是字符數組......還有不少在線的例子,你可以看看包括以下幾個...

Read .CSV file in C

我希望這有助於...

0

您可能不會將scanset格式說明符與其他類型的格式說明符合並在一起。就像你沒有"%df"作爲格式說明符整數浮點數(???)"%si"對於字符串整數(???),你可能沒有像"%d[^,]"這樣的東西。

"%d"只有在遇到','或任何其他非數字字符時纔會放棄閱讀,因此您在此嘗試做的是額外且無效的預防措施。在它旁邊有"[^,]",將導致sscanf在該字符串內查找'[',然後'^',然後',',然後']'

因此,簡而言之,你倒是應該是具有相當簡單的像下面的內容:

#include<stdio.h> 

int main(){ 

    int board; 
    float Res, Ind, Cap; 

    scanf("%d,%f,%e,%e", &board, &Res, &Ind, &Cap); 
    // reads digit sequence until the non-digit input 
    // reads that number into board as an integer 
    // consumes a comma character 
    // and so on... 

    printf("%d\n%f\n%e\n%e", board, Res, Ind, Cap); 

    return 0; 
} 
0

僅尋址:
...我已經試過strtok的......但我好像做錯了什麼....

這將不得不多次完成(最多40次)

聽起來好像你有一個輸入文件的輸入數量可變,最多40個?
所以數據讀取的方式應該適應,並在數據結束時停止讀取。

下面是一個例子做使用strtok()這些事情:

包含這些值的文件:

1.2,345,23,78,234,21.4567,2.45566,23,45,78,12,34,5.678  

我也驗證了它的工作原理與指數符號,如:

1.2,345,23,7.8e3,2.34e-2,21.4567,2.45e-8,2.3e3,45,78,12,34,5.678 

並使用此代碼,strtok的將通過使用分析 「\ n」 作爲分隔符:

#include <ansi_c.h> 

int main(void) 
{ 
    FILE *fp; 
    char *tok; 
    double numbers[100]; 
    char tempBuf[260], lineBuf[260]; 
    int i=0; 

    memset(numbers, 0, sizeof(numbers)/sizeof(numbers[0])*sizeof(int)); 
    fp = fopen("F:\\play3\\numbers.txt", "r"); 
    while(fgets (lineBuf, sizeof(lineBuf), fp)) 
    { 
     tok = strtok(lineBuf, ", \n"); 
     while(tok) 
     { 
      strcpy(tempBuf, tok); 
      if(strlen(tempBuf)>0) 
      { 
       numbers[i++] = strtod(tempBuf, NULL); 
      } 
      tok = strtok(NULL, ", \n"); 

     } 
    } 
    fclose(fp); 
    return 0; 
} 

結果如下
enter image description here