Printf() 乱序打印字符串参数
Printf() prints string arguments out of order
我有一些 C 代码可以逐行读取文本文件,对每行中的字符串进行散列处理,并对具有最大散列值的字符串进行 运行 计数。
它似乎在做正确的事情,但是当我发出打印语句时:
printf("Found Bigger Hash:%s\tSize:%d\n", textFile.biggestHash, textFile.maxASCIIHash);
我在输出中打印 returns 这个:
预处理:dict1
找到 BiSize:110h:a
找到 BiSize:857h:aardvark
找到 BiSize:861h:aardwolf
找到 BiSize:937h:abandoned
找到 BiSize:951h:abandoner
找到 BiSize:1172:abandonment
找到 BiSize:1283:abbreviation
找到 BiSize:1364:abiogenetical
找到 BiSize:1593:abiogenetically
找到 BiSize:1716:absentmindedness
找到 BiSize:1726:acanthopterygian
找到 BiSize:1826:accommodativeness
找到 BiSize:1932:adenocarcinomatous
找到 BiSize:2162:adrenocorticotrophic
找到 BiSize:2173:chemoautotrophically
找到 BiSize:2224:counterrevolutionary
找到 BiSize:2228:counterrevolutionist
找到 BiSize:2258:dendrochronologically
找到 BiSize:2440:electroencephalographic
找到 BiSize:4893:pneumonoultramicroscopicsilicovolcanoconiosis
最大的 Size:46umonoultTotal Words:71885covolcanoconiosis
看来我误用了 printf()。下面是代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define WORD_LENGTH 100 // Max number of characters per word
// data1 struct carries information about the dictionary file; preprocess() initializes it
struct data1
{
int numRows;
int maxWordSize;
char* biggestWord;
int maxASCIIHash;
char* biggestHash;
};
int asciiHash(char* wordToHash);
struct data1 preprocess(char* fileName);
int main(int argc, char* argv[]){
//Diagnostics Purposes; Not used for algorithm
printf("Preprocessing: %s\n",argv[1]);
struct data1 file = preprocess(argv[1]);
printf("Biggest Word:%s\t Size:%d\tTotal Words:%d\n", file.biggestWord, file.maxWordSize, file.numRows);
//printf("Biggest hashed word (by ASCII sum):%s\tSize: %d\n", file.biggestHash, file.maxASCIIHash);
//printf("**%s**", file.biggestHash);
return 0;
}
int asciiHash(char* word)
{
int runningSum = 0;
int i;
for(i=0; i<strlen(word); i++)
{
runningSum += *(word+i);
}
return runningSum;
}
struct data1 preprocess(char* fName)
{
static struct data1 textFile = {.numRows = 0, .maxWordSize = 0, .maxASCIIHash = 0};
textFile.biggestWord = (char*) malloc(WORD_LENGTH*sizeof(char));
textFile.biggestHash = (char*) malloc(WORD_LENGTH*sizeof(char));
char* str = (char*) malloc(WORD_LENGTH*sizeof(char));
FILE* fp = fopen(fName, "r");
while( strtok(fgets(str, WORD_LENGTH, fp), "\n") != NULL)
{
// If found a larger hash
int hashed = asciiHash(str);
if(hashed > textFile.maxASCIIHash)
{
textFile.maxASCIIHash = hashed; // Update max hash size found
strcpy(textFile.biggestHash, str); // Update biggest hash string
printf("Found Bigger Hash:%s\tSize:%d\n", textFile.biggestHash, textFile.maxASCIIHash);
}
// If found a larger word
if( strlen(str) > textFile.maxWordSize)
{
textFile.maxWordSize = strlen(str); // Update biggest word size
strcpy(textFile.biggestWord, str); // Update biggest word
}
textFile.numRows++;
}
fclose(fp);
free(str);
return textFile;
}
你的陈述
while( strtok(fgets(str, WORD_LENGTH, fp), "\n") != NULL)
不考虑 fgets()
的 return 值或 strtok()
的工作方式。
执行此操作的方法类似于
char *fptr, *sptr;
while ((fptr = fgets(str, WORD_LENGTH, fp)) != NULL) {
sptr = strtok(fptr, "\n");
while (sptr != NULL) {
printf ("%s,", sptr);
sptr = strtok (NULL, "\n");
}
printf("\n");
}
请注意,在第一次调用 strtok()
之后,对同一序列的后续调用必须传递参数 NULL
。
您阅读后忘记删除\r
。这是在您的输入中,因为 (1) 您的源文件来自 Windows 机器(或至少使用 \r\n
行结尾的机器),并且 (2) 您使用 fopen
模式"r"
,它不会翻译您的 OS 上的行结尾(同样,大概是 Windows)。
这导致奇怪的输出如下:
发现更大 Hash:text<b>\r</b>\tSize:123
– 看到 \r
的位置了吗?那么当输出这个字符串时会发生什么,你首先得到
Found Bigger Hash:text
然后光标通过 \r
重新定位到行的开头。接下来,输出一个制表符——不是通过打印空格,而是仅仅将光标移动到第 8 个位置:
1234567↓
Found Bigger Hash:text
并且字符串的其余部分打印在已经显示的字符串上:
Found BiSize:123h:text
可能的解决方案:
- 以
"rt"
"text" 模式打开文件,and/or
- 检查并删除
\r
代码以及 \n
。
两者我都愿意。 strchr
非常便宜,可以使您的代码更加万无一失。
(另外,请将您的 fgets
行分成几个不同的操作来简化它。)
我有一些 C 代码可以逐行读取文本文件,对每行中的字符串进行散列处理,并对具有最大散列值的字符串进行 运行 计数。
它似乎在做正确的事情,但是当我发出打印语句时:
printf("Found Bigger Hash:%s\tSize:%d\n", textFile.biggestHash, textFile.maxASCIIHash);
我在输出中打印 returns 这个:
预处理:dict1
找到 BiSize:110h:a
找到 BiSize:857h:aardvark
找到 BiSize:861h:aardwolf
找到 BiSize:937h:abandoned
找到 BiSize:951h:abandoner
找到 BiSize:1172:abandonment
找到 BiSize:1283:abbreviation
找到 BiSize:1364:abiogenetical
找到 BiSize:1593:abiogenetically
找到 BiSize:1716:absentmindedness
找到 BiSize:1726:acanthopterygian
找到 BiSize:1826:accommodativeness
找到 BiSize:1932:adenocarcinomatous
找到 BiSize:2162:adrenocorticotrophic
找到 BiSize:2173:chemoautotrophically
找到 BiSize:2224:counterrevolutionary
找到 BiSize:2228:counterrevolutionist
找到 BiSize:2258:dendrochronologically
找到 BiSize:2440:electroencephalographic
找到 BiSize:4893:pneumonoultramicroscopicsilicovolcanoconiosis
最大的 Size:46umonoultTotal Words:71885covolcanoconiosis
看来我误用了 printf()。下面是代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define WORD_LENGTH 100 // Max number of characters per word
// data1 struct carries information about the dictionary file; preprocess() initializes it
struct data1
{
int numRows;
int maxWordSize;
char* biggestWord;
int maxASCIIHash;
char* biggestHash;
};
int asciiHash(char* wordToHash);
struct data1 preprocess(char* fileName);
int main(int argc, char* argv[]){
//Diagnostics Purposes; Not used for algorithm
printf("Preprocessing: %s\n",argv[1]);
struct data1 file = preprocess(argv[1]);
printf("Biggest Word:%s\t Size:%d\tTotal Words:%d\n", file.biggestWord, file.maxWordSize, file.numRows);
//printf("Biggest hashed word (by ASCII sum):%s\tSize: %d\n", file.biggestHash, file.maxASCIIHash);
//printf("**%s**", file.biggestHash);
return 0;
}
int asciiHash(char* word)
{
int runningSum = 0;
int i;
for(i=0; i<strlen(word); i++)
{
runningSum += *(word+i);
}
return runningSum;
}
struct data1 preprocess(char* fName)
{
static struct data1 textFile = {.numRows = 0, .maxWordSize = 0, .maxASCIIHash = 0};
textFile.biggestWord = (char*) malloc(WORD_LENGTH*sizeof(char));
textFile.biggestHash = (char*) malloc(WORD_LENGTH*sizeof(char));
char* str = (char*) malloc(WORD_LENGTH*sizeof(char));
FILE* fp = fopen(fName, "r");
while( strtok(fgets(str, WORD_LENGTH, fp), "\n") != NULL)
{
// If found a larger hash
int hashed = asciiHash(str);
if(hashed > textFile.maxASCIIHash)
{
textFile.maxASCIIHash = hashed; // Update max hash size found
strcpy(textFile.biggestHash, str); // Update biggest hash string
printf("Found Bigger Hash:%s\tSize:%d\n", textFile.biggestHash, textFile.maxASCIIHash);
}
// If found a larger word
if( strlen(str) > textFile.maxWordSize)
{
textFile.maxWordSize = strlen(str); // Update biggest word size
strcpy(textFile.biggestWord, str); // Update biggest word
}
textFile.numRows++;
}
fclose(fp);
free(str);
return textFile;
}
你的陈述
while( strtok(fgets(str, WORD_LENGTH, fp), "\n") != NULL)
不考虑 fgets()
的 return 值或 strtok()
的工作方式。
执行此操作的方法类似于
char *fptr, *sptr;
while ((fptr = fgets(str, WORD_LENGTH, fp)) != NULL) {
sptr = strtok(fptr, "\n");
while (sptr != NULL) {
printf ("%s,", sptr);
sptr = strtok (NULL, "\n");
}
printf("\n");
}
请注意,在第一次调用 strtok()
之后,对同一序列的后续调用必须传递参数 NULL
。
您阅读后忘记删除\r
。这是在您的输入中,因为 (1) 您的源文件来自 Windows 机器(或至少使用 \r\n
行结尾的机器),并且 (2) 您使用 fopen
模式"r"
,它不会翻译您的 OS 上的行结尾(同样,大概是 Windows)。
这导致奇怪的输出如下:
发现更大 Hash:text<b>\r</b>\tSize:123
– 看到 \r
的位置了吗?那么当输出这个字符串时会发生什么,你首先得到
Found Bigger Hash:text
然后光标通过 \r
重新定位到行的开头。接下来,输出一个制表符——不是通过打印空格,而是仅仅将光标移动到第 8 个位置:
1234567↓
Found Bigger Hash:text
并且字符串的其余部分打印在已经显示的字符串上:
Found BiSize:123h:text
可能的解决方案:
- 以
"rt"
"text" 模式打开文件,and/or - 检查并删除
\r
代码以及\n
。
两者我都愿意。 strchr
非常便宜,可以使您的代码更加万无一失。
(另外,请将您的 fgets
行分成几个不同的操作来简化它。)