4

私はCを学んでいる間、狂ったように研究してきました。私はCプログラムをデバッグしていて、ここでいくつかの大きな問題があると思いました。今、私は重大な問題を抱えています。次のように、1つのステートメントで2つの文字列を出力するダミープログラムを作成しました。

   #include<stdio.h>

int main(int argc, char* argv[])
{
    char *herp = "Derp";
    char *derp = "Herp";

    printf("Herp %s Derp %s\n", herp, derp);

    return 0;
}

これは期待どおりに印刷されます。私は得る

Herp Derp Derp Herp

それで、私は、似たようなことをして自分のプログラムをデバッグさせてみようと思いました。私のプログラムの次の行

printf("word is: %s and jumbled word is: %s\n", word, jumbleWord);

次のようなものを印刷する必要があります

Word is: word and jumbled word is: dowr

しかし、それは次のようなものを印刷します

and jumbled word is: dowr

出力の最初の部分はどこに行きましたか?デバッグするには、これら両方を同じ行に印刷できる必要があります。また、このような発言がうまくいかないという事実は、本当に奇妙なことが起こっていることを私に教えてくれ、私は髪を引き裂くことからはげています。リンクされた投稿が示すように、最終的にこれらの文字列値を比較したいのですが、printf()が正しく機能していない場合、どうすればそれを行うことができますか?

私は以下にプログラム全体を投稿しているので、すべてがどこで起こっているかを見ることができます。ポインタの使い方を学んでいます。単語をごちゃ混ぜにしたいと思ったとき、元々同じメモリに2つのポインタがありましたが、それはうまくいきませんでした。だから私はそれを修正し、必要な単語で2つの別々のメモリスペースを取得しました。今、私はそれらを印刷することができません。以下のコードを考えると、これはすべて理にかなっています。

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

#define MAX_WORD_LENGTH 25

//Define global variables 
int numWords; 

//Preprocessed Functions 
void jumblegame();
void readFile(char *[]);
void jumbleWord(char *);
void guess(char *,char *); 

int main(int argc, char* argv[])
{
    jumblegame();
    return 0;
}

void jumblegame()
{
    //Load File 
        int x = 5050; //Rows
        char *words[x];
        readFile(words);

    //Define score variables 
        int totalScore = 0;
        int currentScore = 0; 

   //Repeatedly pick a random work, randomly jumble it, and let the user guess what it is
         srand((unsigned int)time(NULL));
         int randomNum = rand() % numWords + 1;

         char source[MAX_WORD_LENGTH + 1];
         char jumble[MAX_WORD_LENGTH + 1];

         strncpy(source, words[randomNum], MAX_WORD_LENGTH + 1);
         strncpy(jumble, words[randomNum],MAX_WORD_LENGTH + 1);

         jumbleWord(jumble);

         guess(source, jumble);
         //printf("Random word is: %s\n ", words[randomNum]);
         //randomly jumble it           
}

void readFile(char *array[5049]) 
{
    char line[256]; //This is to to grab each string in the file and put it in a line. 
    int z = 0; //Indice for the array

    FILE *file;
    file = fopen("words.txt","r");

    //Check to make sure file can open 
    if(file == NULL)
    {
        printf("Error: File does not open.");
        exit(1);
    }
    //Otherwise, read file into array  
    else
    {
        while(!feof(file))//The file will loop until end of file
        {
           if((fgets(line,256,file))!= NULL)//If the line isn't empty
           {
             int len = strlen(line); 
             if (len > 0 && line[len - 1] == '\n') line[len - 1] = '\0';
             array[z] = malloc(strlen(line) + 1);
             strcpy(array[z],line);
             z++;
           }    
        }
    }
    fclose(file);
    numWords = z; 
}

void jumbleWord(char *word)
{
    int wordSize = strlen(word) - 1; 
    //durstenfeld Implementation of Fischer-Yates Shuffle
        int i; 
        int j; 
        char temp;
        for(i = wordSize - 1; i > 0; i--)
        {
            j =  rand() % (i + 1);
            temp = word[j];
            word[j] = word[i];
            word[i] = temp;
        }
}

void guess(char *word, char *jumbleWord)
{
     printf("original word is: %s\n", word);
     printf("jumbled word is: %s\n", jumbleWord);
     printf("source is: %s and jumbled word is: %s\n", word, jumbleWord);
}

私はこの時点でほとんどの人がCを燃やし、それをひどく吸うために自分自身を叩くと思います。しかし、私はトラックを続けていきます。ですから、derpについてお詫び申し上げますが、私はおそらく本当に愚かでこれを見つめていることに何時間も費やしてきたことを知っておいてください。「ねえ、Cは私が言っていることをしないのでとても愚かです」と言いたいです。残念ながら、私はこれを信じることができません。私が言っていることを正確に実行していると思いますが、私はこの問題に近すぎて、自分が間違っていることを確認できません。

いつものように、あなたの助けに感謝します。私の最も深い敬意、GeekyOmega

4

2 に答える 2

15

'\r'単語の最後にキャリッジリターンがあります。

キャリッジリターンは、書き込みカーソルを画面の左側に移動するため、書き込みを行っていますが、すでに存在していたものを上書きしています。

于 2012-08-01T19:59:56.697 に答える
2

あなたの単語ファイルには実際に5049エントリがありますか?そうでない場合でも、そうなると思い込まないでください。関数は、ファイルを読み取った後、配列に実際に存在するreadFile単語の数を判別する必要があります。そうしないと、配列にランダムインデックスを取り込むと、初期化されていない文字列にアクセスし、メモリが破損する可能性があります。wordswords

したがって、10readFile語しか表示されない場合は、インデックスからランダムな単語のみを選択する必要があります。メソッド内の可変の単語数をすでに保持しているので、それをコードの残りの部分と共有します。0..9zreadFile

配列にランダムなインデックスを選択する場合、配列は0ベースであるため、有効な配列要素の数だけランダムでmodを取得する必要があることに注意してください。したがって、int randomNum = rand() % 5049;なしで使用して+1ください。

さらに、これらすべてのstrlen/+1/-1ものは不要で混乱を招きます。文字列よりも(および)を優先strncpyし、それに対処する必要はありません。の結果にはヌルターミネータが含まれていないため、でそれを考慮する必要はないことに注意してください。あなたの関数は常にごちゃ混ぜの最後を無視するべきだと思います。memcpystrcpystrlen -1jumbleWordchar

文字列の割り当てには、この戦略を使用してください。ゲーム内の文字列を、またはのいずれかMAX_WORD_LENGTHとして宣言します。文字列をコピーするには、を使用します。char word[MAX_WORD_LENGTH + 1]char *word = malloc(MAX_WORD_LENGTH + 1)strncpy(src, dest, MAX_WORD_LENGTH)

于 2012-08-01T20:02:57.233 に答える