Thread: Write into file with spaces and diacritic.

  1. #1
    Registered User
    Join Date
    Oct 2012
    Location
    Svitavy, Czech Republic
    Posts
    37

    Write into file with spaces and diacritic.

    Hello,
    I want to make program which will write characters from input into a file "soubor.txt" with spaces and diacritic and I would like to know what am I doing wrong here in my code, because output, when I write
    Code:
    Ahoj
    is:
    Code:
    #v·^Gv·^G·^G^G
    This is code:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    
    #define MAX 500
    
    int main(void) {
        fflush(stdin);
        FILE *soubor;    
        int i,j;
        char c[MAX];
        j = 0;
        soubor = fopen("soubor.txt", "w");
            for(i=0;i<=MAX;i++) {
                c[i] = getchar(); 
                if(!(isalpha(c[i])) || !(isdigit(c[i]))) {
                    c[i] = '\0';
                }
                if(c[i] == '\0') {
                    break;
                }
            }
            for(j=0;j<=MAX;j++) {
                if(isspace(c[j])) {
                    c[j] = ' ';
                    break;
                }
                fputs(&c[j], soubor);
            }
    fclose(soubor);
    return 0;
    }

  2. #2
    Registered User
    Join Date
    Nov 2012
    Posts
    1,393
    Quote Originally Posted by maestorm View Post
    Code:
            for(j=0;j<=MAX;j++) {
                if(isspace(c[j])) {
                    c[j] = ' ';
                    break;
                }
                fputs(&c[j], soubor);
            }
    It seems like you are trying to write the string in c character-by-character, but two problems: 1. "&c[j]" produces a pointer to an individual character, and 2.fputs expects a pointer to a null-terminated string. In other words, try to take fputs out of your loop and just do one call:

    fputs(c, soubor);

    Also:

    1. Why do you do fflush(stdin)?
    2. Your first for loop will not null-terminate c in the case that you read MAX characters. It's better to guarantee that c is null-terminated by writing a '\0' to the last position of c. e.g. c[MAX-1] = '\0';

  3. #3
    Registered User
    Join Date
    Oct 2012
    Location
    Svitavy, Czech Republic
    Posts
    37
    Thank you, but now it doesn't work too (sorry I am beginner).
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    
    #define MAX 500
    
    int main(void) {
        FILE *soubor;    
        int i,j;
        char c[MAX];
        j = 0;
        soubor = fopen("soubor.txt", "w");
            for(i=0;i<=MAX;i++) {
                c[i] = getchar(); 
                if(!(isalpha(c[i]))) {
                    c[i] = '\0';
                }
                if(c[i] == '\0') {
                    break;
                }
            }
            for(j=0;j<=c[MAX-1];j++) {
                if(isspace(c[j])) {
                     c[j] = ' ';
                break;
                }
                fputs(c, soubor);
            }
    fclose(soubor);
    return 0;
    }

  4. #4
    Registered User
    Join Date
    Nov 2012
    Posts
    1,393
    Try putting the fputs statement outside of the loop. It only needs to execute one time. You should be able to do it right before closing the file.

  5. #5
    Registered User
    Join Date
    Mar 2010
    Posts
    583
    I don't really understand what you're trying to do. "Spaces and diacritic"?

    I'm guessing that at the moment your code is trying to write the input into a file with all whitespaces (e.g. tabs, newlines) replaced by single space characters? If that's not what it's meant to do, then it'd be helpful if you could explain. If you could show an input line and what you'd expect to see from the output that'd help a lot.

    Code:
            for(i=0;i<=MAX;i++) {
                c[i] = getchar(); 
                if(!(isalpha(c[i]))) {
                    c[i] = '\0';
                }
    This will write '\0' into any non alphabetic character, including digits, spaces, and probably diacritics.

    Code:
                if(c[i] == '\0') {
                    break;
    Then straight away the code will break out of the loop. So it'll only read the characters from the input up to the first non alphabetic character.

    I don't think that's what you intended, since you have code to deal with spaces later. I think you need to pick an "end of string" character in case the input string is less than MAX chars. EOF is the usual one: Ctrl+Z on Windows, CTRL+D on Linux. to check it, do:

    Code:
    if(c[i] == EOF) {
    Code:
            for(j=0;j<=c[MAX-1];j++) {
    Your loop termination condition isn't right here. c[MAX-1] is the last value read into the array. I'd personally say you should be comparing against i here:
    Code:
            for(j=0;j<=i;j++) {
    To output only as much as you input.

    Code:
            for(j=0;j<=c[MAX-1];j++) {
                if(isspace(c[j])) {
                     c[j] = ' ';
                break;
                }
                fputs(c, soubor);
            }
    So, here I think you're trying to go through the whole of c and replace all whitespace characters (tab, newline, space) with a single space character. Then output the resulting string?

    What you code actually does is (assuming the for loop is corrected):
    Code:
            for(j=0;j<=MAX;j++) { // for loop starts here
                if(isspace(c[j])) {  // "if" statement starts
                     c[j] = ' ';
                break;                  // break out of the for loop
                }                        // "if" statement ends
                fputs(c, soubor);   
            }                            // for loop ends
    c always points at the beginning of the string - so each time round the for loop the same string will be printed. I'm not sure why you have a break statement here -- why would you want to stop when you reach a space?

    Sorry if this has been really unhelpful, but I just don't know what you're trying to do!

  6. #6
    Registered User
    Join Date
    May 2012
    Posts
    1,066
    1) You have to work on your indentation!
    2) You have to check if fopen() was successful.
    3)
    Code:
    char c[MAX];
    ...
    for(i=0;i<=MAX;i++) {
    "i" could possibly get up to MAX but the last valid index for your array is MAX - 1, i.e. don't use "<=" in your comparison. Use "<" instead.
    4)
    Code:
    c[i] = getchar();
    "c" is an array of chars but getchar() returns an int.
    5)
    Code:
    for(j=0;j<=c[MAX-1];j++) {
    You probably don't want to compare "j" with the value at c[MAX - 1]. Additionally, c[MAX - 1] will be uninitialised if the user doesn't enter the maximum number of characters.
    6)
    Code:
    if(isspace(c[j])) {
    In your first for-loop you didn't allow to enter any spaces, thus this if-condition will always be false.

    Bye, Andreas

  7. #7
    Registered User
    Join Date
    Oct 2012
    Location
    Svitavy, Czech Republic
    Posts
    37
    So how should correctly working code look like? I am doing this example just for training, but I have problems with writing text into file with spaces few days, please tell me.

  8. #8
    Registered User
    Join Date
    Mar 2010
    Posts
    583
    I still don't understand what it's supposed to do.....

    If I give it the input:

    Hello thèrè
    from smokey



    what is it supposed to write into the file?

  9. #9
    Registered User
    Join Date
    Oct 2012
    Location
    Svitavy, Czech Republic
    Posts
    37
    This program should write into file, what will you write.

  10. #10
    Registered User
    Join Date
    Nov 2012
    Posts
    1,393
    I think the program does what you want, but look closely at this part:

    Code:
    if(!(isalpha(c[i]))) {
                    c[i] = '\0';
                }
    This will stop your input as soon as a non-alphabetic character is detected. Digits, spaces, punctuation and probably letters which contain diacritical markings will thus stop the input.

  11. #11
    Registered User
    Join Date
    Mar 2010
    Posts
    583
    This bit of code:

    Code:
                if(isspace(c[j])) {
                     c[j] = ' ';
    will replace newlines with spaces. isspace() returns true for newlines. Well, course it won't actually get that far because of c99tutorial's point, but assuming it did....
    I don't see any real purpose to this code or the for loop around it. I'd say the latter half of the code can just be:

    Code:
      } //end of first for loop
    
      fputs(c, soubor);
      fclose(soubor);
      return 0;

  12. #12
    Registered User
    Join Date
    Oct 2012
    Location
    Svitavy, Czech Republic
    Posts
    37
    Now my code works, but still it doesn't work for diacritic. How could I make it?
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    
    #define MAX 500
    
    int main(void) {
        FILE *soubor;    
        int i,j;
        char c[MAX];
        j = 0;
        soubor = fopen("soubor.txt", "w");
            for(i=0;i<=MAX;i++) {
                c[i] = getchar();
                if(isspace(c[i])) {
                    c[i] = ' ';
                }
                else if(!(isalpha(c[i]))) {
                    c[i] = '\0';
                    break;
                }
            }
            for(j=0;j<=MAX;j++) {
                if(isspace(c[j])) {
                     c[j] = ' ';
                break;
                }
            }
    fputs(c, soubor);
    fclose(soubor);
    return 0;
    }

  13. #13
    Registered User
    Join Date
    Mar 2010
    Posts
    583
    Using a UTF-8 locale and wchar_t worked for me on Linux, but whether the same approach would work elsewhere is anyone's guess.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <wctype.h>
    #include <locale.h>
     
    #define MAX 500
    
    int main(void) {    
        FILE *soubor;   
        int i,j;
        wchar_t c[MAX];
        setlocale (LC_CTYPE, "en_GB.UTF-8");
        j = 0;
        soubor = fopen("soubor.txt", "w");
            for(i=0;i<=MAX;i++) {
                c[i] = getwchar();
                if(iswspace(c[i])) {
                    c[i] = L' ';
                }
                else if(!(iswalpha(c[i]))) {
                    c[i] = L'\0';
                    break;
                }
            }
            for(j=0;j<=MAX;j++) {
                if(iswspace(c[j])) {
                     c[j] = L' ';
                break;
                }
            }
    fputws(c, soubor);
    fclose(soubor);
    return 0;
    }

  14. #14
    Registered User
    Join Date
    Nov 2012
    Posts
    1,393
    Diacritical characters will probably be considered non-alphabetic characters and thus your test if(!(isalpha(c[i])) will be true. Why not check instead for an EOF condition? Then you can accept all characters.

    Code:
    for(i=0;i<=MAX;i++) {
        int ch = getchar();
        if(isspace(ch)) {
            c[i] = ' ';
        }
        else if(ch == EOF) {
            c[i] = '\0';
            break;
        }
        c[i] = ch;
    }

  15. #15
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    The user-friendly approach is to use the user's chosen locale via setlocale(LC_ALL, ""). Then narrow character classification functions will work as expected.

    gg

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 9
    Last Post: 09-02-2011, 04:57 PM
  2. Adding spaces to existing file
    By 843 in forum C Programming
    Replies: 22
    Last Post: 11-27-2010, 09:24 AM
  3. Replies: 7
    Last Post: 10-03-2009, 10:58 PM
  4. Reading spaces from file
    By arya6000 in forum C Programming
    Replies: 2
    Last Post: 12-08-2007, 12:43 AM
  5. Parsing file for spaces (filter)
    By Lynux-Penguin in forum C++ Programming
    Replies: 1
    Last Post: 11-24-2002, 02:58 PM