char* scanString()
{
char* str = NULL;
char* temp = NULL;
int numOfChars = 0;
char c = '0';
while (c != '\n')
{
scanf(" %c", &c);
if (c != '\n')
{
if (numOfChars == 0)
{
char* str = (char*)malloc(sizeof(char));
char* temp = str;
if (str == NULL)
return str;
str[0] = c;
numOfChars ;
}
else
{
str = (char*)realloc(str, sizeof(char) * (numOfChars 1));
str[numOfChars] = c;
if (str == NULL)
return temp;
else
{
temp = str;
numOfChars ;
}
}
}
}
str = (char*)realloc(str, sizeof(char) * (numOfChars 1));
if (str == NULL)
{
str = temp;
return str;
}
str[numOfChars] = '\0';
return str;
}
int main()
{
char* m;
printf("write:\n");
m = scanString();
printf("%s\n", m);
}
I tried to create a function for scanning a string of unknown size char by char and i don't know what'ss the problem here. Btw please don't approach me to any other code or try to use different libraries.
CodePudding user response:
There is one big error and some inconsistencies.
The big error is here:
if (numOfChars == 0)
{
char* str = (char*)malloc(sizeof(char)); // Oops a new var!
char* temp = str; // and another one!
if (str == NULL)
return str;
str[0] = c;
numOfChars ;
}
You declare 2 new variables in that bloc that will hide the variables of outer scope. As a result, the first character will be lost and you will get a random value.
The inconsistencies:
tmp
is useless and should be removedyou read with a format
" %c"
. The format will skip any blank character including\n
. It should be"%c"
you fail to test the return value of
scanf
. On end of file (of any other read error) you will enter an endless loop. It should be:if (1 != scanf("%c", &c)) break;
Once this is fixed, you should get the expected output, but other improvements are still possible:
- the idiomatic way to read one character is
getc
orgetchar
- allocating one character at a time is an anti-pattern because (re-)allocation is a rather expensive operation. For a realloc world program, you should always allocate a bunch or memory and keep track of the available part
sizeof(char)
is 1 per standard- the distinction for
numOfChars == 0
is useless.realloc
on a NULL pointer is the same ofmalloc
.
CodePudding user response:
Your code is overly complicated and wrong and as stated in a comment you need to replace the format string " %c"
with "%c"
.
The main problem is here:
if (numOfChars == 0)
{
char* str = (char*)malloc(sizeof(char));
You declare a new str
variable which shadows the str
variable you've declared at the beginning of the function.
Just replace char* str = (char*)malloc(sizeof(char))
with str = malloc(sizeof(char));
. BTW the cast is not necessary.
You have the same problem with temp
.
The code below is entirely based on your code, but it is simpler and correct. Basically the case where numOfChars
is 0 should not be treated specially. You can just use realloc
, because realloc(NULL, foo)
is equivalent to malloc(foo)
.
char* scanString()
{
char* str = NULL;
char* temp = NULL;
int numOfChars = 0;
char c = '0';
while (c != '\n')
{
scanf("%c", &c);
if (c != '\n')
{
str = realloc(str, sizeof(char) * (numOfChars 1));
if (str == NULL)
return temp;
str[numOfChars] = c;
temp = str;
numOfChars ;
}
}
str = realloc(str, sizeof(char) * (numOfChars 1));
if (str == NULL)
{
str = temp;
return str;
}
str[numOfChars] = '\0';
return str;
}
Or even simpler:
char* scanString()
{
char* str = NULL;
char* temp = NULL;
int numOfChars = 0;
char c = '0';
while (c != '\n')
{
scanf("%c", &c);
str = realloc(str, sizeof(char) * (numOfChars 1));
if (str == NULL)
return temp;
str[numOfChars] = c;
temp = str;
if (c == '\n')
{
str[numOfChars] = '\0';
}
numOfChars ;
}
return str;
}