0

We created this program in university that creates an array of characters by address in language c. but the first element (char* str) output a weird space. I saw some tutorials about arrays of characters where the first element is the first character we typed.

so why is this happening ? is their some situations where this happens ? if so how can i know if my string starts from the first or second element without using printf everytime ?

This is my program

#include<stdio.h>
#include<stdlib.h>

char* newStr(int n);
int length(char* str);

int main() {
 int n,i;
 printf("Number of characters \n");
 scanf("%d",&n);
 char* str = newStr(n);
 char* c = malloc(n*sizeof(char)+1);
 c=str;

 // check that c[0]=' ' and c[n+1]=\0
 for(i=0;i<=n+1;i++) printf("*(str+%d) = %c \n",i,*(c+i));

 return 0;
}

char* newStr(int n) {
 int i;
 char* c;
 c=malloc(n*sizeof(char)+1);
 printf("Enter a word of %d characters \n",n);
 for(i=0;i<=n;i++) {scanf("%c",(c+i));}
 *(c+n+1)='\0';
 return c;
 }

int length(char* str) {
 int i=0;
 while(*(str+i)!='\0'){i++;}
 return i-1;
}

and this is the output

Number of characters
5
Enter a word of 5 characters
hello
*(str+0) = 

*(str+1) = h
*(str+2) = e
*(str+3) = l
*(str+4) = l
*(str+5) = o
*(str+6) = 
The length of your string is 5

can someone explain it to me in simple termes as i'm quite new to c. thanks in advance

  • `scanf("%d",&n);` does not consume the trailing newline character. Which will be read by the next `scanf`. – kaylum Jan 22 '17 at 23:17
  • 1
    ... after which `scanf("%c",(c+i));` might need to be `scanf(" %c",(c+i));` with that space in there to consume leading whitespace (most other format specs do that automaticaly, but not `%c`). `scanf` is tricky anyway and best avoided. – Weather Vane Jan 22 '17 at 23:21
  • i put a `scanf(" %c",c);` before the loop then added the initial value of i by 1. now it works. thanks – user7454975 Jan 22 '17 at 23:45

2 Answers2

0

Someone already answered in the comments that the scanf() function does not consume the trailing newline char.

So if the user presses "Enter" in their keyboard, and then a scanf() occurs in your code, that Enter press will be recorded.

Also I want to focus your attention in the newStr() function. There you allocate space for a new string and store it in a dynamic array of characters, your char *c, and then return that pointer.

But in your main() you save the return value in str and, for some reason trying to copy it to another pointer(and doing it wrong by the way)?

char* str = newStr(n);
char* c = malloc(n*sizeof(char)+1);
c=str;

str is ALREADY a string you can use, no need to make another malloc on char *c. And when you write c=str; You are actually assigning to the char *c the address of str, not the values pointed by str, thus making this line of code:

char* c = malloc(n*sizeof(char)+1);

Completely useless, and error prone, because you will not be able to free that pointer anymore, having lost the address.

I don't know if I was clear...

Lory
  • 18
  • 7
  • 1
    thanks that was super clear. so the first character is the same one i entered, the problem was with scanf and now i fixed it by put a `scanf(" %c",c);` before the loop then added the initial value of i by 1. don't now if it's the most practical solution but it works. and you're right that char* c is useless – user7454975 Jan 22 '17 at 23:50
0

As already mentioned, scanf("%d",&n) does not consume the new line character, but scanf("%d\n",&n) will.

BTW, just to present a short (but probably hacky) approach, which uses scanf("%20s",...), yet with variable width specifier instead of hardcoded 20:

int n;
char format[20];
scanf("%d\n",&n);
char *result = malloc((n+1) * sizeof(char));
sprintf(format, "%%%ds", n);
scanf(format, result);
Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58