【解決方法】C で FILE data_type を使用してテキストを書き込む方法

プログラミングQA


私は C の初心者です。QT-4 で C を使用しています。 2 つの列を持つテキスト ファイルを書き込もうとしています。
これがスペースで区切られた私のテキストファイルです

C++
hi	Name
hi	Grade
DDD	Class
EEE	Grade2
BBB	Class3
ky	Grade3
DDD	Class4
EEE	Grade4

これが私のコードです

C++
int i, n=2;

char str[50],Name[50],Class[50],Grade[50],var1[50],var2[50];
FILE *fptr;

FORM 読み込み中
更新していません

私は3から得た値でテキストファイル(スペースで区切られた2列)の上に書いています QLineEdits テキストフィールド 文字列が一致する 3 行のテキストをそれぞれ置換します。

私が試したこと:

これが私が試しているコードですが、 動作していません

C++
void newForm::Update(){    
    fptr = fopen("/root/Desktop/simple.txt", "r+");
    char buf[100];        
    #define  VFMT " %29[^ , ]";
    strcpy(Name,widget.lineEdit_1->text().toUtf8());
    strcpy(Class,widget.lineEdit_2->text().toUtf8());
    strcpy(Grade,widget.lineEdit_3->text().toUtf8());
    while(fgets(buf,sizeof buf,fptr) != NULL){
       int n;
       if(3 == sscanf(buf,VFMT " " VFMT " " VFMT "%s", Name "%n",Class"%n",Grade"%n",&n) && buf[n] =='\0'){
            if(fprintf(fptr,VFMT,Name,Class,Grade)<0)
		if (fptr == NULL)
			{
				printf("Could not open file");
			}
		   for(int i=0;i<5;i++) 
		   {
				
			if( strcmp(var2,"Name") == 0)     
			 {
				//out<<std::setw(10)<<Name;
				fprintf(fptr,"\n%s",Name);           
			 }

			if( strcmp(var2,"Class") == 0)
			 {       
				fprintf(fptr,"\n%s",Class);
			 }

			if( strcmp(var2,"Grade") == 0)
			 {
				fprintf(fptr,"\n%s",Grade);
			 }


        }else
            break;
    
    }
    
}

値の書き方 価値 これらの 3 つの行の キー名、クラス、グレード 動作していない上記のコードを使用していますか?
このtxtファイルを書き込み用に解析する方法は?

注:読み取りに成功しました

解決策 1

まず、コードにいくつかの問題があります。 それらに対処する前に、私が行う他のいくつかのことを次に示します。 まず、使用している文字列の型を定義します。 :

const int StrSize = 49;
typedef char textStr[ StrSize + 1 ];

+1 が使用されるため、バッファのサイズからヌル文字のスポットを引いたサイズを取得するために 1 を引く必要はありません。 次に、主に関数内で宣言されたローカル変数を使用します。 これはコードで確認できます。

そのコードについては、3 つのウィジェットから 3 つの変数を更新し、それらの値をファイルのデータで上書きする理由がわかりません。 また、なぜか i 5回ループして、毎回同じデータで同じことをしていますか? それも腑に落ちません。

改訂されたコードに入る前に、データの出力について 1 つの小さな点を述べたいと思います。 可能な限り、カーソルを行の先頭 (位置 0) に置いておくようにしています。 これにより、開始時にどこにあるかが常にわかり、改行文字を行末に配置することで毎回リセットできるため、作業が簡単になります。 リビジョンはこれを行います。

したがって、ここに for ループをオンにした改訂コードがあります i 省略 :

#define  VFMT " %29[^ , ]";

void newForm::Update(){
    FILE * fptr = fopen("/root/Desktop/simple.txt", "r+");
    if (fptr == NULL)
    {
        printf("Could not open file");
        return;
    }

    textStr str, name, class, grade, var1, var2;

    char buf[100] = { 0 };

    // here is the -1 I mentioned previously for the null character

    while(fgets( buf, sizeof( buf ) - 1, fptr ) != NULL){
        int n;
        if(3 == sscanf(buf, VFMT " " VFMT " " VFMT "%s", name"%n", class"%n", grade"%n", &n ) && buf[n] =='\0'){
             const char * text = nullptr;	

             // where is var2 set ????

             if( stricmp( var2,"Name") == 0)    // case insensitive comparison
                 text = name;
             else if( stricmp( var2,"Class") == 0)
                 text = class;
             else if( stricmp( var2,"Grade") == 0)
                 text = grade;
             else
             {
                 fprintf( stderr, "error - unrecognized item : '%s'\n", var2 );
                 break;
             }

             // output value

             fprintf( fptr," %s\n", text );   // add a separating space
        } else
             break;
    }
    fclose( fptr );
}

ここで何が起こっているのか理解できないので、これはあなたが望むことを正確には行いません。 fprintf を使用して幅 3 の固定幅出力を生成するには、次のようにします。

fprintf( fptr, "%3s", stringValue );   // for right-justified text
fprintf( fptr, "%-3s", stringValue );  // for left-justified text

頑張ってください。

解決策 2

ファイルから読み取り中にファイルに書き込もうとしています。これは、データ行がすべてまったく同じ長さであり、読み取りまたは書き込みを行うたびに正しい位置をシークする場合にのみ機能します。通常のテキスト ファイルは悪い考えです。

これは役立つかもしれません: それはデータベースではありません、おい![^]

コメント

タイトルとURLをコピーしました