2017-04-24 13 views
-2

私はテキストファイルで作業していましたが、何とか私は奇妙なエラーが発生しています。私が文字列の第1、第2、第4、第5部分(':'が区切り文字です)を取得しようとすると、私は奇妙な応答を得ます。 :1000:製品:5:0.75これは私が読んしようとしているものです0C:文字列がバッファから正しくコピーされない

そして私は答えのこの種を取得する:ここで

8   |X  |0 
75(

はコードです:

int main(){ 
char c,buff[100],prod[30],id[8],stock[8],vendas[8]; 
int i=0,n=0,num=0; 
FILE *fp; 
fp=fopen("products.txt","r+"); 
printf("Lista de produtos(Num |Produto |Stock |Vendas)\n"); 
while(fgets(buff,100,fp)){ 
for(n=0;n<strlen(buff);n++){ 
    if(buff[n]==':'){ 
    num++; 
    i=0; 
    }  
    else if((buff[n]!=':')&&(num==0)){ 
    id[i]=buff[n]; 
    i++; 
    } 
    else if((buff[n]!=':')&&(num==1)){ 
    prod[i]=buff[n]; 
    i++; 
    } 
    else if((buff[n]!=':')&&(num==3)){ 
    stock[i]=buff[n]; 
    i++; 
    } 
    else if((buff[n]!=':')&&(num=4)){ 
    vendas[i]=buff[n]; 
    i++; 
    }  
    } 
i=0; 
num=0; 
printf("%s |%s    |%s  |%s\n",id,prod,stock,vendas);  
memset(id,0,8); 
memset(prod,0,30); 
memset(stock,0,8); 
memset(vendas,0,8); 
} 
printf("Prima qualquer tecla para sair"); 
getchar(); 
return 0; 
} 

どんな助けもありがとう。申し訳ありませんが、この質問や私のコードは最高ではありません。 素晴らしい一日を!

+3

'%s'書式指定子は、引数としてヌル終了型の変換を期待しています –

+1

ある州から別の州に切り替えるときにこれらの文字列を終了させることを考えているかもしれません。 – WhozCraig

+0

また、strtokを使用して文字列を分割することも考えられます。 – Gerhardh

答えて

0
  • フォーマット文字列が:で始まらない場合は、iを決して初期化しません。
  • :で始まる場合、num==0は決して実行されません。
  • 文字列をヌルにすることは決してありません。
  • if(buff[n]==':') ... else if((buff[n]!=':'は冗長です。
  • num=4はバグです。コンパイラの警告を有効にするか、より良いコンパイラを入手してください。
  • ファイルが正しく開かれたか、ファイルの最後に達したかは決して確認しません。
+0

*フォーマット文字列が:で始まらない場合は、Iを初期化しません。* whileループの最初と最後で 'I'を初期化します。 –

+0

'i'は宣言されたときに初期化されます。 – JeremyP

+0

大丈夫です。なぜ3つの異なる場所で変数を初期化するのですか...最大の混乱のために設計されています。 – Lundin

0

fitst time throughは、各フィールドバッファの内容を初期化していないため、未定義の動作を呼び出します。

のフィールドを埋めるときにも、バッファオーバーランをチェックしません。フィールドは、あなたがそれを入れている配列よりも限り以上である場合には、バッファオーバーランなし。また\0

を終了があるでしょうそれぞれelse ifには(buff[n]!=':')の条件は必要ありません。

また、最後のelse ifは、条件付きn = 4に割り当てられます(実際は結果には影響ありません)。

+0

@AjayBrahmakshatriyaあなたが間違った答えにあなたのコメントを投稿したと思います。 – JeremyP

0

少なくとも2つのエラー:最初にそれらを使用しようとする前に、あなたの配列を初期化

...テストで

while(fgets(buff,100,fp)){ 
    memset(id,0,8); 
    memset(prod,0,30); 
    memset(stock,0,8); 
    memset(vendas,0,8); 
    for(n=0;n<strlen(buff);n++){ 

譲渡、交換してください:

if((buff[n]!=':')&&(num=4)){ 

if((buff[n]!=':')&&(num==4)){ 
         ^

+0

すごく手伝ってくれてありがとう!私はあなたのすべてのヒントを念頭に置いていきます。皆さんに素晴らしい一日をお祈りします。 –

0

あなたそのロジックをもっと難しくする必要があるかもしれません。区切り文字に基づいてテキスト行を単語に分割する必要がある場合は、strtokまたはstrsepと考える必要があります。 strtokは、通常のルーチンです。tokenize区切り文字のテキスト行。個々の単語に改行します。(strsepは、大きな.csvファイルのように、空白フィールドが発生する可能性がある場合に主に使用されます)。

あなたのトークンは':'の文字と最後に'\n'です。あなたは単にchar *delim = ":\n";と宣言し、カバーすることができます。

if, then, else if, ....をデイジーチェーン接続することは自由ですが、カウンタにswitchを追加すると、コードが読みやすくなり、コードが読みやすくなります。

#include <stdio.h> 
#include <string.h> 

enum { ISV = 8, PROD = 30, BUFF = 100 }; /* constants */ 

int main (int argc, char **argv) { 

    char buff[BUFF] = "", prod[PROD] = "", id[ISV] = "", 
     stock[ISV] = "", vendas[ISV] = "", *delim = ":\n"; 
    FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin; 

    if (!fp) { /* validate file open for reading */ 
     fprintf (stderr, "error: file open failed.\n"); 
     return 1; 
    } 

    while (fgets (buff, sizeof buff, fp)) { /* for each line of input */ 
     int i = 0, n = 0; /* tokenize buff into words */ 
     for (char *p = strtok (buff, delim); p; p = strtok (NULL, delim)) { 
      switch (i) { 
       case 0: strncpy (id, p, ISV);  /* handle id */ 
         if (strlen (p) >= ISV) 
          id[ISV-1] = 0; 
          i++; 
         break; 
       case 1: strncpy (prod, p, PROD); /* handle prod */ 
         if (strlen (p) >= PROD) 
          prod[PROD-1] = 0; 
          i++; 
         break; 
       case 2: strncpy (stock, p, ISV); /* handle stock */ 
         if (strlen (p) >= ISV) 
          stock[ISV-1] = 0; 
          i++; 
         break; 
       case 3: strncpy (vendas, p, ISV); /* handle vendas */ 
         if (strlen (p) >= ISV) 
          vendas[ISV-1] = 0; 
          i++; 
         break; 
       default: break; 
      } 
     } 
     n++; 

     printf ("id: %s, prod: %s, stock: %s, vendas: %s\n", 
       id, prod, stock, vendas); 

     if (fp != stdin) fclose (fp); /* close file */ 
    } 
    return 0; 
} 

例入力ファイル

$ cat dat/prod.txt 
1000:Product1:0.75:5:0 
1001:Product2:0.90:2:0 
1002:Product3:0.55:8:0 

使用例/出力

$ ./bin/prod dat/prod.txt 
id: 1000, prod: Product1, stock: 0.75, vendas: 5 
id: 1001, prod: Product2, stock: 0.90, vendas: 2 
id: 1002, prod: Product3, stock: 0.55, vendas: 8 

ルック:一緒にそれらの作品を置く

、次のような何かを行うことができますティあなたはさらに質問がある場合は私に連絡してください。

+0

ありがとうございました!それを完全に理解した。将来的にこれらのヒントを念頭に置いていきます。 –

関連する問題