M@gelearn Ответов: 2

Почему новая линия не находится на том же месте, что и линия, которую Я заменил?


У меня есть этот код, и я пытаюсь заменить строку в a file.txt с новой строкой..

/// Modify a line in a file.txt ///

#include <stdio.h>
#include <conio.h>
#include <windows.h>

#define KEY_UP 72
#define KEY_DOWN 80
#define KEY_ENTER 13

#define MAX 256
#define ARRAYSIZE(sel) (sizeof(sel) / sizeof(sel[0]))
#define SELECT_END 2

struct Info
{
    char name[50];
    char lastname[50];
    char city[50];
    char country[50];
    char tel[20];
}info;

void menu();
void selector(unsigned int select);
void modifyData();
void printFile(FILE *fptr1);
void hideCursor();

int main()
{
    hideCursor();
	menu();

	return 0;
}

void menu()
{
	int select = 0;
    int x;

    selector(select);

    while((x = getch()))
    {
        if(x == KEY_UP)
        {
            select -= 2;
            if(select < 0)
                select = 0;
            selector(select);
        }
        else if(x == KEY_DOWN)
        {
            select += 2;
            if (select > SELECT_END)
                select = SELECT_END;
            selector(select);
        }
        else if(x == KEY_ENTER)
        {
            if(select <= 1)
            {
                modifyData();
				selector(select);
            }
            else if(select <= 2)
            {
                printf("\n\n\n\n\t\t\t    Exiting Data Base");
                Sleep(1000);
                system("cls");
                exit(0);
            }
        }
    }
}

void selector(unsigned int select)
{
	const char *selections[] =
    {
        "\n\n\n\n\n\t1. >  Modify info",
        "\n\n\n\n\n\t1.    Modify info",
        "\t2. >  Exit Data Base",
        "\t2.    Exit Data Base",
    };
    unsigned int i;

    system("cls");
    printf("\n\t\t\t\tData Base\n\t\t\t\t---------");
    printf("\n\n\n\n\n   Select an option using UP and DOWN arrows then press ENTER");

    for(i = 0; i < ARRAYSIZE(selections); i += 2)
    {
        if(i == select)
            printf ("%s\n", selections[i]);
        else
            printf ("%s\n", selections[i + 1]);
    }
}

void modifyData()
{
	FILE *fptr1, *fptr2;
	int newLine;
	char data1[MAX] = "records.txt";
	char data2[MAX];

	system("cls;");
	printf("\n\t\t\t\tData Base\n\t\t\t\t---------");
	printf("\n\n   Replace old info");
	printf("\n   ----------------");


	fptr1 = fopen(data1, "r");
	fptr2 = fopen("temp.txt", "w");

	while(1)
	{
		if(fptr1 == NULL || fptr2 == NULL)
		{
			printf("\n\n\n   Unable to open the input file\n\a");
			Sleep(1000);
			printf("\n   %s", strerror(errno));
			Sleep(1500);
			fclose(fptr1);
			fclose(fptr2);
			remove("temp.txt");
			break;
		}

		fseek(fptr1, 0, SEEK_END);
		long size = ftell(fptr1);
		if(size == 0)
		{
			printf("\n\n   No information in data base\a");
			Sleep(1500);
			fclose(fptr1);
			fclose(fptr2);
			remove("temp.txt");
			break;
		}

		system("cls;");
		printf("\n\t\t\t\tData Base\n\t\t\t\t---------");
		printf("\n\n   Replace old info");
		printf("\n   ----------------\n\n");

		printFile(fptr1);

		fseek(fptr1, 0, SEEK_SET);

		printf("\n\n\n   Update the old info with the following:");
		printf("\n\n\n   New Info");

        printf("\n\n\n\tName:       ");
        scanf("%49s", info.name);
        printf("\n\n\tLast name:  ");
        scanf("%49s", info.lastname);
        printf("\n\n\tCity:       ");
        scanf("%49s", info.city);
        printf("\n\n\tCountry:    ");
        scanf("%49s", info.country);
        printf("\n\n\tPhone:      ");
        scanf("%19s", info.tel);

        fprintf(fptr2, "%s %s %s %s %s\n", info.name, info.lastname, info.city, info.country, info.tel);

        fgets(data2, MAX, stdin);

		printf("\n\n\n   Input the line number you want to replace:  ");
		scanf("%i", &newLine);

		for (int lineCtr = 1; fgets(data1, MAX, fptr1) != NULL; ++lineCtr)
		{
			fprintf(fptr2, "%s", lineCtr != newLine ? data1 : data2);
		}

		fclose(fptr1);
		fclose(fptr2);
		remove("records.txt");
		rename("temp.txt", "records.txt");

		printf("\n\n\n\n\t\t\t Replacement successfully..!");
		Sleep(1500);
		break;
	}
}

void printFile(FILE *fptr1)
{
    rewind(fptr1);

    char data[MAX];

    printf("\n\n");
    for(int line = 0; fgets(data, MAX, fptr1) != NULL;)
    {
        printf(" %i.  %s\n", ++line, data);
    }
}

void hideCursor()
{
    HANDLE cursorHandle = GetStdHandle(STD_OUTPUT_HANDLE);
    CONSOLE_CURSOR_INFO info;
    info.dwSize = 100;
    info.bVisible = FALSE;
    SetConsoleCursorInfo(cursorHandle, &info);
}


Линия заменена, но не так, как я ожидал. file.txt имеет ли это содержание:


Андреа Микеле Рим Италия 3475896523
Анна Стройка Москва Россия 0562314587
Джиджи Бекали Бухарест Румыния 0758963258


.а если я заменю строку 2 следующей строкой Джордж Кали Осло Норвегия 03265897452

Я получаю что-то вроде этого:


Джордж Кали Осло Норвегия 03265897452
Андреа Микеле Рим Италия 3475896523

Джиджи Бекали Бухарест Румыния 0758963258


Что я уже пробовал:

Я удалил эти строки из строки 157:

printf("\n\n\n\tName:       ");
scanf("%49s", info.name);
printf("\n\n\tLast name:  ");
scanf("%49s", info.lastname);
printf("\n\n\tCity:       ");
scanf("%49s", info.city);
printf("\n\n\tCountry:    ");
scanf("%49s", info.country);
printf("\n\n\tPhone:      ");
scanf("%19s", info.tel);

fprintf(fptr2, "%s %s %s %s %s\n", info.name, info.lastname, info.city, info.country, info.tel);


Он принимает входные данные с fgets(data2, MAX, stdin); и я должен записать все данные в пределах 1 одной строки и пробела между словами, и это работает.. но это не то, чего я хочу..

Как заставить его работать с первым кодом?. Я имею в виду, не удаляя кусок кода?

2 Ответов

Рейтинг:
1

Rick York

Я бы попробовал напечатать ваши строки с одинарными кавычками вокруг них, чтобы вы могли видеть, есть ли у вас дополнительные новые строки в некоторых строках. Вы можете сделать это, используя "%s " в качестве спецификатора формата. Если это так, то вам нужно убедиться, что вы удалили их из своего ввода. Когда я читаю данные, я почти всегда сначала убираю новые строки, потому что нахожу, что это упрощает многие вещи.


M@gelearn

Ну я добавляю это:

int len = strlen(data2);
if(data2[len - 1] == '\n')
data2[len - 1] = '\0';

после:

fgets(data2, MAX, stdin);

и я чищу новую линию. Теперь я получаю все строки, включенные в строку, которую я хотел изменить, без какой-либо новой строки между ними.. тем не менее проблема сохраняется, возвращаясь к моему первому вопросу, что строка 2 должна быть удалена, а новая строка должна занять это место, вместо этого моя строка каждый раз занимает первое место.

Rick York

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

Рейтинг:
1

Richard MacCutchan

Лучшим способом было бы сначала прочитать все входные записи в массив Info сооружения. Тогда вам будет гораздо легче найти элемент для замены, а затем записать обновленные данные.