将字符串存储在C中的另一个变量中
Storing a string in another variable in C
我正在编写一个程序来检查给定的字符串是否为回文。我写了一个函数来反转字符串,但无法将反转的字符串存储在不同的变量中。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char stringPalindrome(char s[100], int i, int n){
char reversed = "";
for(i=n;i>=0;i--){
reversed += s[i];
}
return reversed;
}
int main(){
char s[100];
int i,n;
gets(s);
n = strlen(s)-1;
printf("%s", stringPalindrome(s,i,n));
return 0;
}
有没有一种方法可以在不使用 pointers
或 malloc
或 calloc
的情况下将字符串存储在另一个变量中,因为我是这门语言的新手,而且我还有很多东西要学
嗯,没有。
C 中没有 字符串类型。我们只有指向char
的指针。按照惯例,字符串 运行s 从给定位置到后面的第一个零字节。没有办法逃避。
但是为了判断一个字符串是否是回文,你不必先倒转if。只需将第一个字符与最后一个字符进行比较,如果它们与第二个和倒数第二个字符匹配,依此类推。直到一对不匹配。如果你 运行 成对比较(当它们在中间相遇时)字符串是回文。这样您就可以回避创建新字符串的问题。
这里的目标不是检查字符串是否是回文而是反转字符串。
你的代码有几个问题
char reversed = "";
是错误的,reversed是一个char , not a
char*nor a
const char *`
reversed += s[i];
没有像您预期的那样附加 s[i]
- stringPalindrome的参数i没有意义,i必须是局部变量, 不是参数
- 永远不要使用 gets,如果输入比接收数组长,则行为未定义
printf("%s", stringPalindrome(s,i,n));
作为未定义的行为,因为 stringPalindrome return 是 char
而不是字符串
函数stringPalindrome 无法将反向字符串存储在局部变量中,该局部变量是一个字符数组,然后return 该数组具有未定义的行为。您可以让输入字符串不变:
- 在 stringPalindrome 中使用静态局部变量,但函数的每次调用都会修改前一次调用生成的字符串
- 在stringPalindrome中使用malloc在堆中动态分配反向字符串,在这种情况下,调用者有责任释放数组停止使用它
- 还接收存储到参数反转字符串的数组,作为输出参数,在这种情况下,调用者有责任提供足够长的数组来存储结果
在 C 中,函数 strcat 允许连接字符串,但在您的情况下,您想直接添加 one 字符分配该字符而不是使用对 strcat 的昂贵调用(还假设两个字符串都是空终止的)
使用全局变量,函数必须注意不要写出它的静态数组:
#include <stdio.h>
#include <string.h>
char * stringPalindrome(const char * s, size_t n)
{
static char reversed[100];
size_t i;
if (n > sizeof(reversed) - 1)
n = sizeof(reversed) - 1;
for (i = 0; i < n; ++i)
reversed[i] = s[n - i - 1];
reversed[i] = 0;
return reversed;
}
int main()
{
char s[100];
if (fgets(s, sizeof(s), stdin) != NULL)
puts(stringPalindrome(s, strlen(s) - 1));
return 0;
}
编译与执行:
pi@raspberrypi:/tmp $ ./a.out
azer ty
yt reza
pi@raspberrypi:/tmp $
使用动态分配:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char * stringPalindrome(const char * s, size_t n)
{
char * reversed = malloc(n + 1);
size_t i;
for (i = 0; i < n; ++i)
reversed[i] = s[n - i - 1];
reversed[i] = 0;
return reversed;
}
int main()
{
char s[100];
if (fgets(s, sizeof(s), stdin) != NULL) {
char * r = stringPalindrome(s, strlen(s) - 1);
puts(r);
free(r);
}
return 0;
}
编译与执行:
pi@raspberrypi:/tmp $ ./a.out
azer ty
yt reza
pi@raspberrypi:/tmp $
在输出参数中管理结果:
#include <stdio.h>
#include <string.h>
char * stringPalindrome(const char * s, char * reversed, size_t n)
{
size_t i;
for (i = 0; i < n; ++i)
reversed[i] = s[n - i - 1];
reversed[i] = 0;
return reversed;
}
int main()
{
char s[100];
char r[100];
if (fgets(s, sizeof(s), stdin) != NULL) {
puts(stringPalindrome(s, r, strlen(s) - 1));
puts(r);
}
return 0;
}
编译与执行:
pi@raspberrypi:/tmp $ gcc -Wall s.c
pi@raspberrypi:/tmp $ ./a.out
azer ty
yt reza
yt reza
pi@raspberrypi:/tmp $
执行此操作的最简单方法是遍历字符串并比较开始字符和结束字符。使用 fgets()
允许您设置字符串的最大长度,gets()
没有检查所以应该避免。
int palindrom()
{
char s[100];
if (fgets(s,sizeof s,stdin) != NULL)
{
int len = strlen(s);
if (s[len-1] == '\n') --len; // if string is 100 chars there is no \n
for (char* p = s, *q = s + len - 1; p >= q; ++p,--q)
{
if (*p != *q) return 0; // look until difference
}
return 1; // palindrome
}
puts("no input");
return 0;
}
首先,您开始编程真是太好了。
您的代码中有三个小点:
你用的是gets()
,有缓冲区溢出的危险,所以我这里用的是fgets()
。如果你不知道那是什么意思也没关系,因为那是高级的东西,但如果你想知道更多,请告诉我。
在 printf()
中你想打印一个字符串 (%s
) 但是你的函数 stringPalindrome
做 return 一个字符而不是一个数组字符。因此你得到了一个错误。我通过将函数声明为 const char*
类型来修复此问题。另外 char reversed = "";
定义了一个空字符,所以在 for 循环中你试图将字符附加到一个空字符,这会给你一个内存错误。我通过使用第二个字符数组 (r) 解决了这个问题,比如 s 并将他添加到函数调用的参数中。
最后是 for 循环本身。这个问题第二次提出来了pa
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
const char* stringPalindrome(char s[100], char r[100], int i, int p, int n){
for(i=0;i<p;i++){
r[i] = s[n];
n--;
}
return r;
}
int main(){
char s[100];
char r[100];
int i,n,p;
fgets(s, 100, stdin);
p = strlen(s);
n = p-1;
printf("%s", stringPalindrome(s,r,i,p,n));
return 0;
}
我正在编写一个程序来检查给定的字符串是否为回文。我写了一个函数来反转字符串,但无法将反转的字符串存储在不同的变量中。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char stringPalindrome(char s[100], int i, int n){
char reversed = "";
for(i=n;i>=0;i--){
reversed += s[i];
}
return reversed;
}
int main(){
char s[100];
int i,n;
gets(s);
n = strlen(s)-1;
printf("%s", stringPalindrome(s,i,n));
return 0;
}
有没有一种方法可以在不使用 pointers
或 malloc
或 calloc
的情况下将字符串存储在另一个变量中,因为我是这门语言的新手,而且我还有很多东西要学
嗯,没有。
C 中没有 字符串类型。我们只有指向char
的指针。按照惯例,字符串 运行s 从给定位置到后面的第一个零字节。没有办法逃避。
但是为了判断一个字符串是否是回文,你不必先倒转if。只需将第一个字符与最后一个字符进行比较,如果它们与第二个和倒数第二个字符匹配,依此类推。直到一对不匹配。如果你 运行 成对比较(当它们在中间相遇时)字符串是回文。这样您就可以回避创建新字符串的问题。
这里的目标不是检查字符串是否是回文而是反转字符串。
你的代码有几个问题
char reversed = "";
是错误的,reversed是一个char , not a
char*nor a
const char *`reversed += s[i];
没有像您预期的那样附加s[i]
- stringPalindrome的参数i没有意义,i必须是局部变量, 不是参数
- 永远不要使用 gets,如果输入比接收数组长,则行为未定义
printf("%s", stringPalindrome(s,i,n));
作为未定义的行为,因为 stringPalindrome return 是char
而不是字符串
函数stringPalindrome 无法将反向字符串存储在局部变量中,该局部变量是一个字符数组,然后return 该数组具有未定义的行为。您可以让输入字符串不变:
- 在 stringPalindrome 中使用静态局部变量,但函数的每次调用都会修改前一次调用生成的字符串
- 在stringPalindrome中使用malloc在堆中动态分配反向字符串,在这种情况下,调用者有责任释放数组停止使用它
- 还接收存储到参数反转字符串的数组,作为输出参数,在这种情况下,调用者有责任提供足够长的数组来存储结果
在 C 中,函数 strcat 允许连接字符串,但在您的情况下,您想直接添加 one 字符分配该字符而不是使用对 strcat 的昂贵调用(还假设两个字符串都是空终止的)
使用全局变量,函数必须注意不要写出它的静态数组:
#include <stdio.h>
#include <string.h>
char * stringPalindrome(const char * s, size_t n)
{
static char reversed[100];
size_t i;
if (n > sizeof(reversed) - 1)
n = sizeof(reversed) - 1;
for (i = 0; i < n; ++i)
reversed[i] = s[n - i - 1];
reversed[i] = 0;
return reversed;
}
int main()
{
char s[100];
if (fgets(s, sizeof(s), stdin) != NULL)
puts(stringPalindrome(s, strlen(s) - 1));
return 0;
}
编译与执行:
pi@raspberrypi:/tmp $ ./a.out
azer ty
yt reza
pi@raspberrypi:/tmp $
使用动态分配:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char * stringPalindrome(const char * s, size_t n)
{
char * reversed = malloc(n + 1);
size_t i;
for (i = 0; i < n; ++i)
reversed[i] = s[n - i - 1];
reversed[i] = 0;
return reversed;
}
int main()
{
char s[100];
if (fgets(s, sizeof(s), stdin) != NULL) {
char * r = stringPalindrome(s, strlen(s) - 1);
puts(r);
free(r);
}
return 0;
}
编译与执行:
pi@raspberrypi:/tmp $ ./a.out
azer ty
yt reza
pi@raspberrypi:/tmp $
在输出参数中管理结果:
#include <stdio.h>
#include <string.h>
char * stringPalindrome(const char * s, char * reversed, size_t n)
{
size_t i;
for (i = 0; i < n; ++i)
reversed[i] = s[n - i - 1];
reversed[i] = 0;
return reversed;
}
int main()
{
char s[100];
char r[100];
if (fgets(s, sizeof(s), stdin) != NULL) {
puts(stringPalindrome(s, r, strlen(s) - 1));
puts(r);
}
return 0;
}
编译与执行:
pi@raspberrypi:/tmp $ gcc -Wall s.c
pi@raspberrypi:/tmp $ ./a.out
azer ty
yt reza
yt reza
pi@raspberrypi:/tmp $
执行此操作的最简单方法是遍历字符串并比较开始字符和结束字符。使用 fgets()
允许您设置字符串的最大长度,gets()
没有检查所以应该避免。
int palindrom()
{
char s[100];
if (fgets(s,sizeof s,stdin) != NULL)
{
int len = strlen(s);
if (s[len-1] == '\n') --len; // if string is 100 chars there is no \n
for (char* p = s, *q = s + len - 1; p >= q; ++p,--q)
{
if (*p != *q) return 0; // look until difference
}
return 1; // palindrome
}
puts("no input");
return 0;
}
首先,您开始编程真是太好了。 您的代码中有三个小点:
你用的是
gets()
,有缓冲区溢出的危险,所以我这里用的是fgets()
。如果你不知道那是什么意思也没关系,因为那是高级的东西,但如果你想知道更多,请告诉我。在
printf()
中你想打印一个字符串 (%s
) 但是你的函数stringPalindrome
做 return 一个字符而不是一个数组字符。因此你得到了一个错误。我通过将函数声明为const char*
类型来修复此问题。另外char reversed = "";
定义了一个空字符,所以在 for 循环中你试图将字符附加到一个空字符,这会给你一个内存错误。我通过使用第二个字符数组 (r) 解决了这个问题,比如 s 并将他添加到函数调用的参数中。最后是 for 循环本身。这个问题第二次提出来了pa
#include<stdio.h> #include<stdlib.h> #include<string.h> const char* stringPalindrome(char s[100], char r[100], int i, int p, int n){ for(i=0;i<p;i++){ r[i] = s[n]; n--; } return r; } int main(){ char s[100]; char r[100]; int i,n,p; fgets(s, 100, stdin); p = strlen(s); n = p-1; printf("%s", stringPalindrome(s,r,i,p,n)); return 0; }