为什么代码会出现segmentation fault?有时它不会发生
why does the code occur segmentation fault? sometimes it not occur
我想将句子中的 space 替换为“%20”。
例如:
Input:"How are you?"
Output:"How%20are%20you?"
而且我在短句中成功做到了,但是当我使用 20+ space 时。
例如:
Input:" "
Output: segementation falut
希望能找到原因,谢谢大家。
这是我在 C:
中的代码
char* replaceSpace(char* s ) {
// write code here
int len = strlen(s);//to mark the length of s
for(int i = 0; i < len; i++)
{
if(s[i] == 32)
{
len = len + 2;
for(int j = 0; j < len-i-1; j++){
s[len-j] = s[len-j-2];
}
s[i] = '%';
s[i+1] = '2';
s[i+2] = '0';
}
}
return s;
}
非常感谢。
你不能像那样动态增加长度。您正在访问 s 之外的 un-allocated 索引,同时引用它,因此导致段错误。
当您尝试访问内存的未分配部分时,通常会发生分段错误。
此问题的可能解决方法是创建一个新字符串并正常复制所有字符(space 除外)。对于您遇到的每个 space 字符,您将其替换为“%20”。因此新字符串的长度将是它包含的 space 的三倍加上其余字符(如果有的话)。
#include <stdio.h>
#include <stdlib.h>
// Construct an ADT called String
typedef struct {
char *str;
size_t length;
size_t str_size;
} String;
// Initialize our ADT
String *initStr(void);
// Free the memory allocated for `String`
void destroyStr(String *);
// Get input from `stdin`
String *input(char *);
// Count the total number of given
// character in the string
size_t count(String *, char);
// Replace each spaces in the string
// with its hex value
String *convert(String *);
int main(void)
{
String *s = input("Input: ");
s = convert(s);
printf("Output: %s\n", s->str);
destroyStr(s);
return 0;
}
String *initStr(void)
{
String *s = malloc(sizeof(String));
s->str = malloc(sizeof(char));
s->str[0] = '[=10=]';
s->length = 0;
s->str_size = 1;
return s;
}
String *input(char *label)
{
printf("%s", label);
String *s = initStr();
int c;
while ((c = getc(stdin)) != '\n' && c != EOF) {
// Dynamically allocate string. If the string
// length is equal to the internal size, allocate
// twice as of current length.
if (s->length + 1 == s->str_size) {
size_t ssize = s->str_size;
s->str = realloc(
s->str, 2 * ssize * sizeof(char)
);
if (s->str == NULL)
return NULL;
s->str_size = 2 * ssize;
}
s->str[s->length++] = c;
}
s->str[s->length] = '[=10=]';
return s;
}
void destroyStr(String *s)
{
free(s->str);
free(s);
}
size_t count(String *s, char c)
{
size_t count = 0;
for (size_t i = 0; i < s->length; ++i)
if (s->str[i] == c)
++count;
return count;
}
String *convert(String *old_s)
{
size_t total_spaces = count(old_s, ' ');
// Return the original string if there are
// no spaces in it
if (total_spaces == 0)
return old_s;
// The new string will contain thrice as many characters
// for each space plus the other characters
size_t new_s_len = (
3 * total_spaces +
old_s->length - total_spaces
);
String *new_s = initStr();
new_s->str = malloc( (new_s_len + 1) * sizeof(char) );
new_s->str_size = new_s_len + 1;
for (size_t i = 0; i < old_s->length; ++i) {
if (old_s->str[i] == ' ') {
new_s->str[new_s->length++] = '%';
new_s->str[new_s->length++] = '2';
new_s->str[new_s->length++] = '0';
}
else
new_s->str[new_s->length++] = old_s->str[i];
}
new_s->str[new_s->length] = '[=10=]';
destroyStr(old_s);
return new_s;
}
由于 C 没有任何 built-in String
数据类型,我们尝试使用 struct
和字符数组来模拟数据类型。我们还必须自己处理内存管理。这可能会变得很麻烦,并且通常与实际问题没有那么密切的关系。因此,我建议您转向 C++ 或 Rust。
我想将句子中的 space 替换为“%20”。 例如:
Input:"How are you?"
Output:"How%20are%20you?"
而且我在短句中成功做到了,但是当我使用 20+ space 时。 例如:
Input:" "
Output: segementation falut
希望能找到原因,谢谢大家。 这是我在 C:
中的代码char* replaceSpace(char* s ) {
// write code here
int len = strlen(s);//to mark the length of s
for(int i = 0; i < len; i++)
{
if(s[i] == 32)
{
len = len + 2;
for(int j = 0; j < len-i-1; j++){
s[len-j] = s[len-j-2];
}
s[i] = '%';
s[i+1] = '2';
s[i+2] = '0';
}
}
return s;
}
非常感谢。
你不能像那样动态增加长度。您正在访问 s 之外的 un-allocated 索引,同时引用它,因此导致段错误。
当您尝试访问内存的未分配部分时,通常会发生分段错误。
此问题的可能解决方法是创建一个新字符串并正常复制所有字符(space 除外)。对于您遇到的每个 space 字符,您将其替换为“%20”。因此新字符串的长度将是它包含的 space 的三倍加上其余字符(如果有的话)。
#include <stdio.h>
#include <stdlib.h>
// Construct an ADT called String
typedef struct {
char *str;
size_t length;
size_t str_size;
} String;
// Initialize our ADT
String *initStr(void);
// Free the memory allocated for `String`
void destroyStr(String *);
// Get input from `stdin`
String *input(char *);
// Count the total number of given
// character in the string
size_t count(String *, char);
// Replace each spaces in the string
// with its hex value
String *convert(String *);
int main(void)
{
String *s = input("Input: ");
s = convert(s);
printf("Output: %s\n", s->str);
destroyStr(s);
return 0;
}
String *initStr(void)
{
String *s = malloc(sizeof(String));
s->str = malloc(sizeof(char));
s->str[0] = '[=10=]';
s->length = 0;
s->str_size = 1;
return s;
}
String *input(char *label)
{
printf("%s", label);
String *s = initStr();
int c;
while ((c = getc(stdin)) != '\n' && c != EOF) {
// Dynamically allocate string. If the string
// length is equal to the internal size, allocate
// twice as of current length.
if (s->length + 1 == s->str_size) {
size_t ssize = s->str_size;
s->str = realloc(
s->str, 2 * ssize * sizeof(char)
);
if (s->str == NULL)
return NULL;
s->str_size = 2 * ssize;
}
s->str[s->length++] = c;
}
s->str[s->length] = '[=10=]';
return s;
}
void destroyStr(String *s)
{
free(s->str);
free(s);
}
size_t count(String *s, char c)
{
size_t count = 0;
for (size_t i = 0; i < s->length; ++i)
if (s->str[i] == c)
++count;
return count;
}
String *convert(String *old_s)
{
size_t total_spaces = count(old_s, ' ');
// Return the original string if there are
// no spaces in it
if (total_spaces == 0)
return old_s;
// The new string will contain thrice as many characters
// for each space plus the other characters
size_t new_s_len = (
3 * total_spaces +
old_s->length - total_spaces
);
String *new_s = initStr();
new_s->str = malloc( (new_s_len + 1) * sizeof(char) );
new_s->str_size = new_s_len + 1;
for (size_t i = 0; i < old_s->length; ++i) {
if (old_s->str[i] == ' ') {
new_s->str[new_s->length++] = '%';
new_s->str[new_s->length++] = '2';
new_s->str[new_s->length++] = '0';
}
else
new_s->str[new_s->length++] = old_s->str[i];
}
new_s->str[new_s->length] = '[=10=]';
destroyStr(old_s);
return new_s;
}
由于 C 没有任何 built-in String
数据类型,我们尝试使用 struct
和字符数组来模拟数据类型。我们还必须自己处理内存管理。这可能会变得很麻烦,并且通常与实际问题没有那么密切的关系。因此,我建议您转向 C++ 或 Rust。