我在学习C的过程中一直在疯狂地研究。我一直在调试一个C程序,我认为我遇到了一些重大问题here。现在我有关键问题。我制作了一个虚拟程序,在一个语句中打印两个字符串,如下所示:
#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()不能正常工作,我怎么能这样做呢?
我发布下面的整个程序,这样你就可以看到一切都在发生。我只是在学习如何使用指针。当我想混淆一个单词并且效果不好时,我最初有两个指针指向相同的内存!所以我修复了它,并用我需要的单词获得了两个独立的内存空间。现在,我只是无法打印它们。根据以下代码,这一切都有意义:
#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而自我sla sla。但是,我将继续保持卡车运输。所以,让我为任何derp道歉,但请知道我花了很多时间可能是非常愚蠢的,并盯着这个。我很想说,“嘿,C是如此愚蠢,因为它不会做我告诉它的事情”。不幸的是,我无法相信这一点。我认为这正是我正在告诉它要做的事情,但我太接近这个问题,看看我做错了什么。
一如既往,感谢您的帮助。我最深的敬意, GeekyOmega
答案 0 :(得分:15)
在单词的末尾有一个回车'\r'
。
回车将写入光标移动到屏幕左侧,因此它正在写入,但它会覆盖已存在的内容。
答案 1 :(得分:2)
你的单词文件实际上有5049
个条目吗?即使它没有,你也不应该认为它确实如此。您的readFile
函数应该在读取文件后确定words
数组中实际中有多少个单词,否则,将随机索引带入words
数组将导致访问未初始化的字符串,我怀疑这会导致你的内存损坏。
因此,如果readFile
只看到 10 字,那么您应该只选择索引0..9
之间的随机字。您已经在z
方法中将变量readFile
中的单词数保留,并与其余代码共享。
当你在一个数组中选择一个随机索引时,请注意,由于数组是基于0的,你应该得到有效数组元素的随机和正好mod。因此,请使用int randomNum = rand() % 5049;
而不使用+1
。
此外,所有这些strlen/+1/-1
内容都是不必要且令人困惑的,更喜欢strncpy
而不是memcpy
(和strcpy
)字符串,而您无需处理。请注意,strlen
的结果不会包含空终结符,因此您无需考虑-1
的结果。我认为您的jumbleWord
函数应该始终忽略混乱中的最后一个char
。
将此策略用于字符串分配:您拥有MAX_WORD_LENGTH
,将游戏中的字符串声明为char word[MAX_WORD_LENGTH + 1]
或char *word = malloc(MAX_WORD_LENGTH + 1)
。现在要复制字符串,请使用strncpy(src, dest, MAX_WORD_LENGTH)
。