这个问题似乎很容易描述,但很难理解。希望有经验的朋友可以帮助我:很简单,再一次:
1.当我通过Code::Blocks(mingw安装)编译我的C代码或程序时,它工作得非常好,并生成一个54 kb的文件,该文件完全按照预期工作。(耶)。
1.但是,当我通过gcc编译相同的C代码或程序时,无论是在cmd中还是在emacs中-编译都是成功的(41 kb文件大小),但是:我执行的时候代码就完成了一半。(??)它不打印它应该打印的东西(或任何东西)。它只是开始,然后结束(在cmd上快速)。不管我是在shell还是cmd中运行它,还是在代码块自己的cmd-thing上运行。(也就是说,如果我通过gcc编译它,然后执行main。exe文件通过代码块)。
(3.额外:问题中的程序是C编程书问题1中的问题。13:它接受一堆单词,并检查它们的长度,然后使用“”打印出垂直直方图。|当我通过Code::blocks编译它时,它执行得非常好;但是当我在emacs或cmd上通过gcc运行它时,它只是工作了一点,然后退出,根本没有打印任何行。所以我知道这是一个编译器问题,但我不知道如何修复它。我更愿意在将来通过gcc编译,但是如果编译的代码块版本更好,那么我别无选择,只能放弃gcc?你告诉我,因为我在这件事上很愚蠢。
我已经做了几个来回(删除主要。exe,并使用两者重新编译它。结果相同:代码块可以工作,GCC不行。)-是的exe文件。在这两个版本上编译都“成功”-但是gcc版本没有按它应该的那样执行。
我完全无用的猜测是,getchar()函数的行为很奇怪,这取决于使用它的编译器。
感谢您的评分
我将添加代码的问题,如果你需要它,或者如果你想判断我。(我不介意任何批评。)
#include <stdio.h>
#define MAXLENGTH 25 /* Maximum length of input. */
int main(){
/* Histogram of length of words in its input. Vertical or Horizontal. (Vertical is hardest, so let's do that!).
* Identify words and count characters within each, store that length in a array that represents the length for each word.
* Draw based on the number of words, their lengths, and their maximum height (optional).
*/
/* Identify when inside of a word, start counting. When leaving word, record c-count into array, reset count to 0 after.
* Until entering new word.
*/
//Declaration of the Counter's variables here
//The Histogram's variables are farther down below!
int nw, c, cCount, wordLen[MAXLENGTH];
int i = nw = cCount = 0;
//Initialize wordLen into 0 to avoid garbage results from any potential unused members of the array.
for (i = 0; i < 25; i++) {
wordLen[i] = 0;
}
//Counts characters in each word and stores inside of chronological array.
while ((c = getchar())!= EOF){
if (c == ' ' || c == '\t' || c == '\n'){
wordLen[nw] = cCount;
++nw;
cCount = 0;
}
else {
++cCount;
}
}
//Prints first 4 words lengths for comparison purposes.
printf("%d %d %d %d\n\n", wordLen[0], wordLen[1], wordLen[2], wordLen[3]);
//Declaration of variables for Histogram.
int currentLvl, largestN, ii, iii, IV, V;
//Finds and stores the largest number from the array into var:largestN.
for (ii = 0; ii < MAXLENGTH; ii++) {
if (wordLen[ii] >= largestN)
largestN = wordLen[ii];
}
//Declare and initialize array for comparison purposes for later use in the Histogram generation process.
int level[largestN];
level[0] = 0;
for (iii = 1; iii < largestN + 1; iii++){
level[iii] = iii;
}
// printf("\n largest N is %d\n", largestN); //for testing
// printf("wordLen 0 is: %d\n", wordLen[0]); //for testing
/* Histogram generation:
* The logic is simple: From Top-left, move rightwards (in chronological order) and check which of the words' lengths
* reach the current level or height (starting from Top). Print a line at that spot if they ever do, print an empty space if
* they do not.
* Then move one step down, and repeat the process but comparing 1 level lower. Until bottom is reached.
*/
//ss
for (V = largestN; V > 0; V--){
currentLvl = level[V];
for (IV = 0; IV < MAXLENGTH; IV++){
if (wordLen[IV] >= currentLvl)
printf("|");
else {
printf(" ");
}
printf(" ");
}
printf("\n");
}
return 0;
}
编辑1:
当我编译+运行它通过代码块的例子:
(
这是一个句子:
asdasdasd
4 2 1 8
|
| |
| |
| |
| |
| | |
| | |
| | | |
| | | | |
)
这是使用emacs(使用gcc编译器后)- shell:
(
B:\c-programs\Examples〉main.exe main.exe
这是一个句子asdasdasd
B:\c-programs\Examples〉Process shell完成
)
哦,我忘了说一句:我必须做ctrl-d或ctrl-c来“完成”程序后,键入句子,以便它开始打印图形。也许这跟它有关系?
编辑2:这里看起来很奇怪,但在cmd屏幕上的注解字段/中看起来很好(代码块)。
编辑3:* 修复编辑部分中的一些缺失信息。*
编辑4:解决感谢大家的投入,我会阅读和学习,我可以从你们每一个人!问题是,我似乎没有初始化largestN(如你所说),但我也学到了很多其他的东西,我会尝试吸收!所以谢谢你!祝你好运,我也有你的项目!!
4条答案
按热度按时间vohkndzv1#
您的代码中可能有一些错误。在这里,您将
wordLen[ii]
与未初始化且可能具有任何值的largestN
进行比较。如果
largestN
持有像641346
这样的值,你试图用它创建一个数组:顺便说一句,你可以有一个变量的多个循环。
ma8fv8wu2#
请注意,第45行定义的largestN没有初始化,并且可以包含非常大的值。像Code::blocks这样的IDE很可能会将所有变量归零,而gcc生成的更多优化编译则不会。因此,你可能会得到非常高的“酒吧”,基本上混乱了你的屏幕,使它很难看到什么是键入。
只需按以下方式更改第45行,这可能会给予您一些更合理的结果:
另外,如果你已经在使用它,就不需要i,ii,iii等等,因为你在每次循环中都重置这个计数器,你可以在任何地方使用相同的变量'i'。此外,它不是标准的C语言,但所有现代编译器都允许你在for循环中定义一个变量,这更安全(注意for循环中的“int i”):
l7wslrjt3#
正如其他答案所说,您正在与未初始化的
largestN
进行比较,并调用undefined behavior。这里有另一个潜在的解决方案在这里,您只处理正值,因此将
largestN
初始化为0就可以了,但一般来说,初始化为数组中已经存在的值是更健壮的方法。如果你的数组都是负数怎么办?那么0会大于所有这些,你不会得到一个准确的结果。sqxo8psd4#
有几个问题..
1.有几个地方发生UB。
1.存储到
wordLen
时,nw
可以超过MAXLENGTH
1.在您的示例输入文件中,有超过25个(即即
MAXLENGTH
)字。1.我们需要检查一下是否有多余的。
largestN
是 uninitialized,所以它可以有一个随机的[bad]值。1.后面的一些数组循环到
MAXLENGTH
。它们应该只循环到nw
(有效元素的 * 实际 * 数量)。1.某些环路硬连接到
25
,而不是MAXLENGTH
level
数组定义得太小。1.从原点1开始的索引超出数组的末尾,并使第一个元素保持为单位化。
这里是[大部分]更正的代码。它是一个[大多数]错误和修复的注解。它可能在打印中仍然有一些错误,但它修复了大多数严重的错误:
在上面的代码中,我使用了
cpp
条件来表示old与新代码:注意:这可以通过
unifdef -k
运行文件来清理。