2016-03-23 3 views
0

Я довольно новичок в программировании, и это мой первый вопрос, поэтому, надеюсь, я не сломаю (слишком много) правила! Мне обычно нравится разбираться самостоятельно, но я в тупике, так что вот так:Преобразование строки в формате FN LN в LN, FN (John Doe to Doe, John) в C

У меня есть задание для курса по компьютерной науке II, который просит меня создать/записать мое имя в файл (скажем, Джон Доу), а затем выводит содержимое этого файла. Эта часть, которую я смог выполнить.

Теперь вторая половина задания говорит мне написать и использовать функцию, которая преобразует мое имя в имя Фамилия, Формат имени и записывает его в отдельный файл. Он не указывает мне, чтобы я выводил содержимое указанного файла, но я все равно хочу.

Я не совсем уверен, как подойти к преобразованию имени. Должен ли я создать две разные строки для моего имени и фамилии (я думал об этом, но это не показалось особенно эффективным)? Это также не похоже на ситуацию, которая должна требовать использования структуры, но я мог бы (и, вероятно, я) полностью отказаться от этого. Вот что у меня есть до сих пор:

#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); 
    } 
} 

Любые ответы или предложения приветствуются. Даже просто подталкивание в правильном направлении было бы потрясающе. Кроме того, любые предложения/критические замечания по поводу моего сообщения также приветствуются, так что я могу улучшить их в будущем. Спасибо за ваше время!

+1

[почему 'в то время! Feof (readPtr)' неправильно] (http://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong) – Barmar

+0

Да, используйте две строки , Используйте '% s' в' fscanf' для чтения одного слова в каждой строке. Затем вы можете использовать 'printf', чтобы записать их во второй файл в другом порядке, чем вы их читали. – Barmar

ответ

1

Во-первых, вы должны иметь код, который преобразует «FN LN» в «LN, FN» в отдельной функции. Функция должна распределять память, так как форма LN, FN содержит еще два символа (запятая и пробел).

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; 
} 

Теперь, для основного кода. while (!feof()) неверен, потому что индикатор EOF установлен после Чтение потерпело неудачу, а не раньше. Таким образом, цикл будет работать еще раз, чем предполагалось. Законченный код

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; 
} 

Примечание: Я не тестировал main, поэтому, если есть ошибки, дайте мне знать.

+0

'fscanf (fp,"% s ", name);' неверно. – BLUEPIXY

+0

Что в этом плохого? @BLUEPIXY Должен ли я добавить спецификатор ширины, чтобы избежать переполнения? – stackptr

+0

'% s' семейства' scanf' не содержит пробелов. Таким образом, он работает не так, как ожидалось. (_Should я добавить спецификатор ширины, чтобы избежать переполнения? _ Да :) – BLUEPIXY

0

Это один из способов.

  1. Имя [] написал FNLNnamefile.txt
  2. Имя [] очищается
  3. FNLNnameFile.txt датировать Имя []
  4. Имя [] выписал LNFNnamefile.txt Имя [] является распечатывается в разных точках.

Да это незначительные «обмануть» в конце с простым элементом реверса, хотя когда-то прочитал в 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); 
} 
Смежные вопросы