gpt4 book ai didi

c - 程序适用于字符串文字,但不适用于字符串数组

转载 作者:行者123 更新时间:2023-11-30 15:33:03 25 4
gpt4 key购买 nike

我有一个哈希表 ADT,它有两个函数:插入和查找。我将哈希表、哈希表大小、ID # 和书名放入插入函数中,然后将其插入到哈希表中。当我向它传递字符串文字时,它工作得很好,即 insert(...,"Hello, world!"...); 当我从文件中读取字符串时,它不起作用,将它们存储在数组中,并尝试使用我的插入和查找函数。我的所有代码都在这里,但最重要的文件是 main.c 和 hash.c。 Hash.c 具有 newHash()、hash()、insert() 和 Lookup() 函数,main.c 从两个文件(在本例中为 test1.lib.in 和 test1.req.in)读取,并从第一个文件读取file 将从每一行获取一本书的图书馆 ID 和标题,然后将其放入哈希表中。从第二个文件中,它获取对书名的请求,并应在其链接列表中打印 id。

有效的代码示例。

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "list.h"
#include "hash.h"

int main(){
ListHndl* temp = newHash(10);
insert(442440, "cvyaqbznxel", 10,temp);
lookup(temp,"cvyaqbznxel", 10);
return 0;
}

无效的代码

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include "list.h"
#include "hash.h"


int main(int argc, char * argv[]) {

if (argc != 3) {
printf("Incorrect arguments, please specify 2 files to be read\n");
return EXIT_FAILURE;
}
FILE *file = fopen( argv[1], "r");
FILE *secondFile = fopen(argv[2], "r");
if (file == 0 || secondFile == 0) {
printf("Could not open a file\n");
return EXIT_FAILURE;
}
int numDataLines2;
int numDataLines;
int hashTableSize;
//First line of first file gives number of lines in file and
//size of hash table to be made
if(fscanf(file, "%d%d", &numDataLines, &hashTableSize) < 2) {
printf("Unable to parse first line of first file\n");
return EXIT_FAILURE;
}
ListHndl* theHash = newHash(hashTableSize);
int libraryID;
char *tempString = calloc(numDataLines,41*sizeof(char));
char lineHolder[129];
//discard the new line which always shows up
fgets(lineHolder, 128, file);
for(int i = 0; i < numDataLines; i++) {
//Gets the whole line to be scanned with sscanf
fgets(lineHolder, 128, file);

//If the line consists of just a newline char, continue
if(strcmp(lineHolder, "\n") == 0 ) {
continue;
}
//Scans the line retrieved from fgets and placed in lineHolder
if(sscanf(lineHolder, "%d, %40[^\n]", &libraryID,&tempString[i]) == 0){
printf("Unable to parse line %d of first file\n",i+2);
return EXIT_FAILURE;
}
insert(libraryID, &tempString[i], hashTableSize, theHash);
}
char String[41];
fgets(String, 40, secondFile);
numDataLines2 = atoi(String);
char *storeSecondFileStuff = calloc(numDataLines2,41*sizeof(char));
for(int i = 0; i< numDataLines2; i++) {
fgets(lineHolder, 128, secondFile);
if(strcmp(lineHolder, "\n") == 0) {
continue;
}
if(sscanf(lineHolder, "%40[^\n]",&storeSecondFileStuff[i]) == 0) {
printf("Unable to parse line %d of second file\n",i+2);
return EXIT_FAILURE;
}
lookup(theHash, &storeSecondFileStuff[i], hashTableSize);
}
printf("\n");
fclose(file);
fclose(secondFile);
return 0;
}

谢谢!

最佳答案

我认为您有多个问题。首先,您可能没有正确扫描输入行。更改线路

 if(sscanf(lineHolder, "%d, %40[^\n]", &libraryID,&tempString[i]) == 0)

 if(sscanf(lineHolder, "%d, %40[^\n]", &libraryID, tempString) < 0)

这样,你就会陷入sscanf的情况函数未成功转换两个参数 - 例如,如果输入行中没有逗号。请注意sscanf返回成功转换的次数;成功将返回值 2 ,因此测试 <2这是正确的方法。

另请注意,我更改了 &tempString[i]tempString 。前者指向 tempString 沿线的某个地方- 只分配了 41 个字符。然而,您总是允许最多写入 40 个字符(加上 '\0' ) - 因此您将写入超过字符串末尾的内容。由于这只是一个临时变量,因此这样做没有任何意义。只需扫描输入进入临时变量,然后用它做任何你需要做的事情。

这意味着您的 insert也发生变化,从

    insert(libraryID, &tempString[i], hashTableSize, theHash);

    insert(libraryID, tempString, hashTableSize, theHash);

同样,您需要在代码中做同样的事情。

这里尝试让代码为您工作 - 看看这是否合适。请注意,我真正所做的只是更改 tempString 的类型和storeSecondFileStuff ,并相应地修改了它们在各种函数调用中的使用方式。由于涉及的其他文件的复杂性,我没有尝试编译/运行 - 但这应该会有所帮助:

int main(int argc, char * argv[]) {

if (argc != 3) {
printf("Incorrect arguments, please specify 2 files to be read\n");
return EXIT_FAILURE;
}
FILE *file = fopen( argv[1], "r");
FILE *secondFile = fopen(argv[2], "r");
if (file == 0 || secondFile == 0) {
printf("Could not open a file\n");
return EXIT_FAILURE;
}
int numDataLines2;
int numDataLines;
int hashTableSize;
//First line of first file gives number of lines in file and
//size of hash table to be made
if(fscanf(file, "%d%d", &numDataLines, &hashTableSize) < 2) {
printf("Unable to parse first line of first file\n");
return EXIT_FAILURE;
}
ListHndl* theHash = newHash(hashTableSize);
int libraryID;
char **tempString = calloc(numDataLines,sizeof(char*)); // <<< ARRAY of pointers
char lineHolder[129];
//discard the new line which always shows up
fgets(lineHolder, 128, file);
for(int i = 0; i < numDataLines; i++) {
//Gets the whole line to be scanned with sscanf
fgets(lineHolder, 128, file);
tempString[i] = calloc(1, 41 * sizeof(char)); // <<< space for this string
//If the line consists of just a newline char, continue
if(strcmp(lineHolder, "\n") == 0 ) {
continue;
}
//Scans the line retrieved from fgets and placed in lineHolder
if(sscanf(lineHolder, "%d, %40[^\n]", &libraryID, tempString[i]) < 0){ // <<< changed
printf("Unable to parse line %d of first file\n",i+2);
return EXIT_FAILURE;
}
insert(libraryID, tempString[i], hashTableSize, theHash); // <<< changed
}
char String[41];
fgets(String, 40, secondFile);
numDataLines2 = atoi(String);
char **storeSecondFileStuff = calloc(numDataLines2, sizeof(char*)); // changed: again char **
for(int i = 0; i< numDataLines2; i++) {
fgets(lineHolder, 128, secondFile);
storeSecondFileStuff[i] = calloc(1, 41 * sizeof(char));
if(strcmp(lineHolder, "\n") == 0) {
continue;
}
if(sscanf(lineHolder, "%40[^\n]",storeSecondFileStuff[i]) == 0) {
printf("Unable to parse line %d of second file\n",i+2);
return EXIT_FAILURE;
}
lookup(theHash, storeSecondFileStuff[i], hashTableSize); // <<<< changed
}
printf("\n");
fclose(file);
fclose(secondFile);
return 0;
}

关于c - 程序适用于字符串文字,但不适用于字符串数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23840215/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com