- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我已经尝试并搜索了此问题。如果我尝试从列表中删除一个字符串,则会收到“ 3221225477”作为返回值。
我已经尝试过使用其他方法,例如更改'return value [];'在const char * del(ListNodePtr * strPtr,value [])函数中将“返回* value;”如果您能告诉我我应该在代码中进行哪些更改,将不胜感激。
这就是我定义结构的方式。我不知道这是否真的很好。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct listnode
{
char data[100];
listnode *nextPtr;
};
typedef struct listnode ListNode;
typedef ListNode *ListNodePtr;
void insert(ListNodePtr *strPtr, char value[])
{
ListNodePtr previousPtr, currentPtr, newPtr;
newPtr=(listnode*)malloc(sizeof(listnode));
strcpy(newPtr->data,value);
newPtr->nextPtr=NULL;
previousPtr=NULL;
currentPtr=*strPtr;
if(newPtr!=NULL)
{
while(currentPtr!=NULL &&
strcmp(currentPtr->data,value)<0)
{
previousPtr=currentPtr;
currentPtr=currentPtr->nextPtr;
}
if(previousPtr==NULL)
{
newPtr->nextPtr=*strPtr;
*strPtr=newPtr;
}
else
{
previousPtr->nextPtr=newPtr;
newPtr->nextPtr=currentPtr;
}
}else printf("%s was not inserted. Insuffiecient memory!",value);
}
const char *del(ListNodePtr *strPtr, char value[])
{
ListNodePtr previousPtr, currentPtr, tempPtr;
if(strcmp(value, (*strPtr)->data)==0) /*if the
first node shall be deleted*/
{
/*delete node*/
tempPtr=*strPtr;
*strPtr=(*strPtr)->nextPtr;
free(tempPtr);
return *value;
}
else
{
previousPtr=*strPtr;
currentPtr=(*strPtr)->nextPtr;
while(currentPtr!=NULL && strcmp(value,
currentPtr->data)!=0)
{
previousPtr=currentPtr;
currentPtr=currentPtr->nextPtr;
}
if(currentPtr!=NULL)
{
tempPtr=currentPtr;
previousPtr- >nextPtr=currentPtr->nextPtr;
free(tempPtr);
return *value;
}
}
return '\0';//if the node is not found
}
int main()
{
ListNodePtr startPtr;
startPtr=NULL;
int optiune;
char nume[100];
instructions();
printf("? ");
scanf("%d",&optiune);
while(optiune!=3)
{
switch(optiune)
{
case 1:
printf("Enter name:");
fflush(stdin);
gets(nume);
insert(&startPtr, nume);
printList(startPtr);
break;
case 2:
fflush(stdin);
printf("Search by name to delete from list:");
gets(nume);
if(!Empty(startPtr))
{
if(del(&startPtr, nume))
{
printf("%s was deleted!\n");
printList(startPtr);
}else printf("%s was not found!\n",nume);
}else
printf("List is empty!");
break;
case 3:
break;
default:
printf("No such option!\n\n");
instructions();
break;
}
printf("\n? ");
scanf("%d",&optiune);
}
printf("Execution stopped.\n" );
return EXIT_SUCCESS;
最佳答案
问题中的代码有很多小问题,但是当这些问题被清除后,核心算法似乎可以正常工作。缩进在某些地方有点奇怪。从现在开始,我将忽略该问题。
不幸的是,批评可以很快开始:
struct listnode
{
char data[100];
listnode *nextPtr;
};
typedef struct listnode ListNode;
typedef ListNode *ListNodePtr;
listnode *nextPtr;
在C中无效(但在C ++中有效)。在那一行,名称
struct listnode
是已知的,但是没有任何
listnode
前缀的类型
struct
在任何标准标头中都没有定义(通常情况下,无论如何)。您需要
struct listnode *nextPtr;
是有效的C。或者您需要将
typedef struct listnode ListNode;
移到结构定义之前,然后在结构中使用
ListNode *nextPtr;
。您可能不应该定义或使用
ListNodePtr
-有关原因的讨论,请参见
Is it a good idea to typedef pointers?。您可以像这样清理代码。请注意,结构标签(如
ListNode
)位于标签名称空间(以及
union
标签和
enum
标签),但typedef名称
ListNode
位于不同的“普通标识符”名称空间中-因此没有这段代码中
ListNode
的使用之间存在冲突:
typedef struct ListNode ListNode;
struct ListNode
{
char data[100];
ListNode *nextPtr;
};
ListNode
代替
ListNodePtr
或任何其他变体拼写。
insert()
中的代码就可以了;错误消息应打印到
stderr
,并进行拼写检查,并以换行符结尾。
del()
中的代码可能不在函数
delete()
中,因为
delete
是C ++编译器中的关键字,因此不能用作函数名。不要使用C ++编译器来编译C,否则会产生误导性的结果。
const char *
,但是返回的值不是指针。最好更改该函数以返回
int
或什至
bool
以指示其是否成功删除了指定名称。
previousPtr - > nextPtr = currentPtr->nextPtr;
.
或箭头
->
运算符之间不应有空格,并且
-
和
>
之间也没有空格,您甚至没有正式的箭头运算符。
del()
中的核心算法似乎可以正常工作。可能还有改进的空间。
Empty()
,
printList()
,
instructions()
之类的未定义(实际上是未声明)的函数-创建MCVE(
Minimal, Complete, Verifiable Example)时,不应遗漏这样的内容。下面的代码为每种方法提供了简单的实现。
main()
中的代码显示了各种问题。一种是通过不编写有用的功能来完成特定工作的代码重复。我不知道您对
instructions()
函数的计划是什么,但是我保留了它,并将其简化为打印单个提示的
printf()
(末尾没有换行符)。它本身是从处理许多复杂细节的函数
get_option()
中使用的。
gets()
函数;了解为什么
it is far too dangerous to use gets()
— ever!。另外,将
scanf()
与
fgets()
之类的功能混合会有点麻烦,因为
scanf()
leaves the newline in the input buffer。我创建了函数
get_option()
和
get_string()
来处理问题,并处理无效(非数字)输入和意外的EOF等。它们还刷新标准输出,但不刷新标准输入。参见
Using fflush(stdin)
进行细微的讨论-可以说
fflush(stdin)
不是可移植的,尽管它确实在Windows上定义了行为,但是除了调用未定义的行为外,它在其他任何地方都几乎没有做。通常,避免使用它。如果必须使用它,请注意限制了代码的可移植性(通常没有必要这样做)。
main()
主体中的代码稍微简单一些。我在
case 2:
代码中对测试进行了重新排序,以避免嵌套ifs。通常最好是在测试后做一些事情,而不是开始新的测试。
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct ListNode ListNode;
struct ListNode
{
char data[100];
ListNode *nextPtr;
};
extern void insert(ListNode **strPtr, char value[]);
extern bool delete(ListNode **strPtr, char value[]);
void insert(ListNode **strPtr, char value[])
{
ListNode *previousPtr, *currentPtr, *newPtr;
newPtr = (ListNode *)malloc(sizeof(ListNode));
strcpy(newPtr->data, value);
newPtr->nextPtr = NULL;
previousPtr = NULL;
currentPtr = *strPtr;
if (newPtr != NULL)
{
while (currentPtr != NULL &&
strcmp(currentPtr->data, value) < 0)
{
previousPtr = currentPtr;
currentPtr = currentPtr->nextPtr;
}
if (previousPtr == NULL)
{
newPtr->nextPtr = *strPtr;
*strPtr = newPtr;
}
else
{
previousPtr->nextPtr = newPtr;
newPtr->nextPtr = currentPtr;
}
}
else
fprintf(stderr, "%s was not inserted. Insufficient memory!\n", value);
}
bool delete(ListNode **strPtr, char value[])
{
ListNode *previousPtr, *currentPtr, *tempPtr;
if (strcmp(value, (*strPtr)->data) == 0)
{
tempPtr = *strPtr;
*strPtr = (*strPtr)->nextPtr;
free(tempPtr);
return true;
}
else
{
previousPtr = *strPtr;
currentPtr = (*strPtr)->nextPtr;
while (currentPtr != NULL && strcmp(value, currentPtr->data) != 0)
{
previousPtr = currentPtr;
currentPtr = currentPtr->nextPtr;
}
if (currentPtr != NULL)
{
tempPtr = currentPtr;
previousPtr->nextPtr = currentPtr->nextPtr;
free(tempPtr);
return true;
}
}
return false;
}
static bool Empty(ListNode *ptr)
{
return(ptr == NULL);
}
static void get_string(size_t size, char buffer[size])
{
if (fgets(buffer, size, stdin) == 0)
{
fprintf(stderr, "Unexpected EOF on standard input\n");
exit(EXIT_FAILURE);
}
buffer[strcspn(buffer, "\n")] = '\0';
}
static void instructions(void)
{
printf("1 to add, 2 to delete, 3 to exit: ");
}
static int get_option(void)
{
int optiune;
instructions();
fflush(stdout);
if (scanf("%d", &optiune) != 1)
{
fprintf(stderr, "Failed to read option number\n");
exit(EXIT_FAILURE);
}
int c;
while ((c = getchar()) != EOF && c != '\n')
;
return optiune;
}
static void printList(ListNode *ptr)
{
for (int i = 0; ptr != NULL; i++)
{
printf("%d: %s\n", i, ptr->data);
ptr = ptr->nextPtr;
}
}
int main(void)
{
ListNode *startPtr;
startPtr = NULL;
int optiune;
char nume[100];
while ((optiune = get_option()) != 3)
{
switch (optiune)
{
case 1:
printf("Enter name: ");
fflush(stdout);
get_string(sizeof(nume), nume);
insert(&startPtr, nume);
printList(startPtr);
break;
case 2:
printf("Search by name to delete from list: ");
fflush(stdout);
get_string(sizeof(nume), nume);
if (Empty(startPtr))
printf("List is empty!\n");
else if (delete(&startPtr, nume))
{
printf("%s was deleted!\n", nume);
printList(startPtr);
}
else
printf("%s was not found!\n", nume);
break;
default:
fprintf(stderr, "No such option (%d)!\n\n", optiune);
break;
}
}
printf("Execution stopped.\n");
return EXIT_SUCCESS;
}
static
,除非有一个标头在其中声明它们,以及另一个将使用它们的源文件。这甚至可以帮助优化,因为编译器可以告知
static
函数被调用的频率以及我的内联代码)
1 to add, 2 to delete, 3 to exit: 1
Enter name: Patricia
0: Patricia
1 to add, 2 to delete, 3 to exit: 1
Enter name: Persephone
0: Patricia
1: Persephone
1 to add, 2 to delete, 3 to exit: 1
Enter name: Piglet
0: Patricia
1: Persephone
2: Piglet
1 to add, 2 to delete, 3 to exit: 1
Enter name: Pooh
0: Patricia
1: Persephone
2: Piglet
3: Pooh
1 to add, 2 to delete, 3 to exit: 1
Enter name: Puss In Boots
0: Patricia
1: Persephone
2: Piglet
3: Pooh
4: Puss In Boots
1 to add, 2 to delete, 3 to exit: 1
Enter name: Pygmalion
0: Patricia
1: Persephone
2: Piglet
3: Pooh
4: Puss In Boots
5: Pygmalion
1 to add, 2 to delete, 3 to exit: 2
Search by name to delete from list: Pooh
Pooh was deleted!
0: Patricia
1: Persephone
2: Piglet
3: Puss In Boots
4: Pygmalion
1 to add, 2 to delete, 3 to exit: 2
Search by name to delete from list: Pygmalion
Pygmalion was deleted!
0: Patricia
1: Persephone
2: Piglet
3: Puss In Boots
1 to add, 2 to delete, 3 to exit: 2
Search by name to delete from list: Patricia
Patricia was deleted!
0: Persephone
1: Piglet
2: Puss In Boots
1 to add, 2 to delete, 3 to exit: 2
Search by name to delete from list: Piglet
Piglet was deleted!
0: Persephone
1: Puss In Boots
1 to add, 2 to delete, 3 to exit: 2
Search by name to delete from list: Puss In Boots
Puss In Boots was deleted!
0: Persephone
1 to add, 2 to delete, 3 to exit: 2
Search by name to delete from list: Quantum Gold
Quantum Gold was not found!
1 to add, 2 to delete, 3 to exit: 2
Search by name to delete from list: Persephone
Persephone was deleted!
1 to add, 2 to delete, 3 to exit: 3
Execution stopped.
关于c - 如何使用函数从列表中删除字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53990832/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!