Learning C
Learning C

Reputation: 689

I can't code it to copy a string

#include <stdio.h>

char converter(char input[]);
char getInformation (char input[]);

int main(){

  char c[99];
  int i;

  printf("Enter a Line:");
  scanf("%c", &c);

  while(i < 99){
    printf("%c\n", &c[i]);
    i++;
  }

}

Results for when I tried to run this

z:~/homework1: gcc -o hw1_1 hw1_1.c
z:~/homework1: hw1_1
Enter a Line:Test
Ø
Ù
Ú
Û
Ü
Ý
Þ
ß
à
á
â
ã
ä
å
æ
ç
è
é
ê
ë
ì
í
î
ï
ð
ñ
ò
ó
ô
õ
ö
÷
ø
ù
ú
û
ü
ý
þ
ÿ





































1
2
3
4
5
6
7
8
9
:
z:~/homework1:

I'm trying to get it to read a text and print it out. Is there a way I can set the array to undefined number and how would I implement that into the while loop? Also can I have some guidance of how to check every character and change it's case (from lower case to upper case and the other way around). I think I can do this by checking the ASCII value of the character and flipping the numbers. For example if the character is a decimal value from 65-90, which are A-Z, I would add 32 to it to make it small. For character from 97-122, a-z, I would subtract 32. I don't need the answer but some hits would be nice. Thank you.

So far I've made these changes.

#include <stdio.h>

char converter(char input[]);
char getInformation (char input[]);

int main(){

  char c[30];
  int i;

  printf("Enter a Line: ");
  fgets(c, sizeof(c), stdin);


  i=0;
  while( i < sizeof(c)){
    printf("%s", c[i]);
    i++;
  }

}

This is what I get after trying to run this.

z:~/homework1: gcc -o hw1_1 hw1_1.c
z:~/homework1: hw1_1
Enter a Line: Test
Segmentation fault (core dumped)
z:~/homework1: z:~/homework1:

Yes I got it! thanks a lot everyone!! Here is the code

    #include <stdio.h>

int main(){

  char c[BUFSIZ];
  int i;

  printf("Enter a Line: ");
  fgets(c, BUFSIZ, stdin);

  i=0;
  for (i=0; i < sizeof(c); i++){

    if ((c[i] >= 65) && (c[i] <= 90) ){
      c[i] = c[i]+32;
    }else {
      if ((c[i] >=97) && (c[i] <= 122) ){
        c[i] = c[i]-32;
      }
    }
  }

and the results when I run it:

z:~/homework1: gcc -o hw1_1 hw1_1.c
z:~/homework1: hw1_1
Enter a Line: TeoijsTY;' ';lasd
tEOIJSty;' ';LASD

z:~/homework1:

This is the best feeling you can have, writing a working code! I wonder if I post this and my professors does a Google check of my code and think that I plagiarized? Anyways thanks a lot for the help.

Upvotes: 0

Views: 146

Answers (3)

paxdiablo
paxdiablo

Reputation: 881293

scanf("%c", &c); will scan in a single character. to c[0]. It will not scan in a line.

Then your loop will print out 99 characters at a random location since you haven't initialised i to 0. Even if you had, you would print out all 99 characters, most of which are uninitialised.

That's why you're not getting a line, and why you're seeing rubbish in the output.

For line-based input, you need to look into fgets, which can safely input a line from the user (it has prevention of buffer overflow built in). Then, once you have the line, you can just use printf ("%s\n", c) or puts(c) to output it - no need to process it a character at a time.

If you're looking for a good way to use fgets, see here. The full function is probably unsuitable for a homework assignment at this level but you can look at the code to see how it works. You shouldn't copy it verbatim unless you want to be accused of plagiarism but, by all means, use it to educate yourself.

Bottom line:

fgets (buff, size, handle);

will read characters from the file handle handle (use stdin for user input) into memory at buff, limited in size by size.

The getLine function linked above will handle the edge cases like end-of-file detection, user entering a too-long line for the buffer and so on.

Function duplicated below for completeness:

#include <stdio.h>
#include <string.h>

#define OK       0
#define NO_INPUT 1
#define TOO_LONG 2
static int getLine (char *prmpt, char *buff, size_t sz) {
    int ch, extra;

    // Get line with buffer overrun protection.
    if (prmpt != NULL) {
        printf ("%s", prmpt);
        fflush (stdout);
    }
    if (fgets (buff, sz, stdin) == NULL)
        return NO_INPUT;

    // If it was too long, there'll be no newline. In that case, we flush
    // to end of line so that excess doesn't affect the next call.
    if (buff[strlen(buff)-1] != '\n') {
        extra = 0;
        while (((ch = getchar()) != '\n') && (ch != EOF))
            extra = 1;
        return (extra == 1) ? TOO_LONG : OK;
    }

    // Otherwise remove newline and give string back to caller.
    buff[strlen(buff)-1] = '\0';
    return OK;
}

Upvotes: 0

Daniel Fischer
Daniel Fischer

Reputation: 183868

When you read in a line via scanf, you use the format specifier for a char, you should use %s or, preferably, %98s to avoid overflow. On the other hand, when printing the characters one by one, you should pass the character itself as an argument to printf and not its address, so there it should be printf("%c\n",c[i]);.

To avoid printing out more characters than have been read in, you can first zero-fill the char-array, then scan with a width less than the array size to guarantee that you have a 0-terminated string in the array, and in the printing loop, check that c[i] != 0.

For the case conversions, the header <ctype.h> contains the necessary functions, that's better than to code them yourself. If you're not allowed to use them, your plan with the comparison with 'A' = 65 etc. works well for ASCII characters, but you may need to also consider characters in the range 128-255 (depends on your assignment).

Upvotes: 0

pmr
pmr

Reputation: 59811

scanf isn't really suited to reading a whole line. Use fgets.

char c[99];
fgets(c, 99, stdin);

Upvotes: 2

Related Questions