0

I'm fairly new to programming and this is my first question here so hopefully I don't break any (too many) rules! I usually like to figure things out on my own but I'm stumped so here goes:

I have an assignment for my computer science II course that's asking me to create/write my name to a file (let's say John Doe) and then output the contents of that file. This part I've been able to accomplish.

Now the 2nd half of the assignment is telling me to write and use a function that converts my name into Last Name, First name format and write it to a separate file. It doesn't specifically tell me to output the contents of said file but I want to anyway.

I'm not exactly sure how to approach converting the name. Should I create 2 different strings for my first and last name (I thought about doing this but it didn't seem particularly efficient)? It also doesn't seem like a situation that should require utilizing a struct, but I could be (and probably am) completely off on that. Here's what I have so far:

#include <stdio.h>
#define SIZE 20


int main(void)
{
    FILE *readPtr;//readfile.txt file pointer
    FILE *writePtr;//writefile.txt file pointer
    char nameFull[SIZE] = "John Doe";


    readPtr = fopen("readfile.txt", "w");//creates readfile.txt file for writing
    fprintf(readPtr, "%s", nameFull);//writes contents of string "nameFull" to file
    fclose(readPtr);//close file

    if((readPtr = fopen("readfile.txt", "r")) == NULL){//returns error message if file can't be opened
        printf("Error opening file!\n");
    }
    else{
        while(!feof(readPtr)){//end of file check for readPtr file

            fscanf(readPtr, "%[^\n]s", nameFull);
            printf("\n%s\n\n", nameFull);

        }
        fclose(readPtr);
    }
}

Any answers or suggestions are greatly appreciated. Even just a nudge in the right direction would be awesome. Also, any suggestions/criticism about my post are welcome too, so that I may improve them going forward. Thanks for your time!

Teej
  • 3
  • 2
  • 1
    [why `while !feof(readPtr)` is wrong](http://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong) – Barmar Mar 23 '16 at 21:59
  • Yes, use two strings. Use `%s` in `fscanf` to read one word into each string. Then you can use `printf` to write them to the second file in a different order than you read them. – Barmar Mar 23 '16 at 22:01

2 Answers2

1

First, you should have the code that converts "FN LN" to "LN, FN" in a separate function. The function is going to have to allocate memory, since the LN, FN form contains two more characters (the comma and the space).

char *revname(const char *fnln)
{
    char *buf;

    /* +2 for space and comma, +1 for null terminator */
    if ((buf = malloc(strlen(fnln) + 3)) != NULL) {
        char *p, *q;
        size_t len;

        /* find the first space in the string */
        if ((p = strchr(fnln, ' ')) != NULL) {
            /* copy the text after the space */
            strcpy(buf, p + 1);
            strcat(buf, ", ");

            len = strlen(buf);

            /* append the first name */
            for (q = (char *) fnln; q < p; ++q)
                buf[len++] = *q;
        }
        /* null terminate the string */
        buf[len] = '\0';
    }
    return buf;
}

Now, for the main code. while (!feof()) is wrong, because the EOF indicator is set after a reading has failed, not before. Thus, the loop will run once more than intended. The completed code is

void remlast(char *str) { str[strlen(str) - 1] = '\0'; }
int main()
{
    FILE *fp;
    char name[20], *newname;

    if ((fp = fopen("filename", "w")) != NULL) {
        /* write the name onto the file */
        fputs("John Doe", fp);

        /* reuse the same file pointer for reading */
        if ((fp = freopen("filename", "r", fp)) != NULL) {
            fgets(name, 20, fp);

            /* remove the trailing newline from fgets */
            remlast(name);

            newname = revname(name);
            printf("%s\n", newname);

            /* free memory allocated by revname */
            free(newname);
            fclose(fp);
        } else {
            perror("freopen");
            return 1;
        }
    } else {
        perror("fopen");
        return 1;
    }
    return 0;
}

Note: I haven't tested main, so if there are bugs let me know.

lost_in_the_source
  • 10,998
  • 9
  • 46
  • 75
0

Here is one method.

  1. Name[ ] written to FNLNnamefile.txt
  2. Name[ ] cleared
  3. FNLNnameFile.txt read back into Name[ ]
  4. Name[ ] written out to LNFNnamefile.txt Name[ ] is printed out at various points.

Yes it is a minor "cheat" at the end with simple element reverse, though once read into the Name[ ] the order can by manipulated by another function, be it swap or lexicographically or word length order or whatever by passing it Name[ ].

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

#define     EXIT_FAIL       0x01
#define     MAX_WORD_LEN    0x1F
#define     MAX_WORDS       0x02

int main(void)
{
    FILE            *fptr_MyFile;
    unsigned char   *ucName[MAX_WORDS];
    unsigned char   ucWord[MAX_WORD_LEN];
    unsigned int    uiW0;

    ucName[0x00] = "John";
    ucName[0x01] = "Doe";

    printf("Name array  %s %s\n\n", ucName[0x00], ucName[0x01]);

    fptr_MyFile = fopen("FNLNnamefile.txt", "w");
    if (fptr_MyFile == NULL)
        {
        printf("Could not create file.  Ending.\n");
        return(EXIT_FAIL);
        }
    fprintf(fptr_MyFile, "%s %s", ucName[0x00], ucName[0x01]);
    fclose(fptr_MyFile);

    if ((fptr_MyFile = fopen("FNLNnamefile.txt", "r")) == NULL)
        {
        printf("Could not create file.  Ending.\n");
        return(EXIT_FAIL);
        }

    ucName[0x00] = NULL;
    ucName[0x01] = NULL;

    printf("Name array  %s %s\n\n", ucName[0x00], ucName[0x01]);

    for (uiW0 = 0x00; ((uiW0 < MAX_WORDS) && (!feof(fptr_MyFile))); uiW0 = uiW0 + 0x01)
        {
        fscanf(fptr_MyFile, "%s", ucWord);
        ucName[uiW0] = calloc(strlen(ucWord) + 1, sizeof(char));
        strcpy(ucName[uiW0], ucWord);
        }
    fclose(fptr_MyFile);

    printf("Name array   %s %s\n\n", ucName[0x00], ucName[0x01]);

    fptr_MyFile = fopen("LNFNnamefile.txt", "w");
    if (fptr_MyFile == NULL)
        {
        printf("Could not create file.  Ending.\n");
        return(EXIT_FAIL);
        }
    fprintf(fptr_MyFile, "%s, %s", ucName[0x01], ucName[0x00]);
    fclose(fptr_MyFile);

    printf("Final result    %s, %s\n", ucName[0x01], ucName[0x00]);

    return(EXIT_SUCCESS);
}
SkyPirate
  • 35
  • 6