Z
Z
ZIK13372019-04-22 17:50:25
C++ / C#
ZIK1337, 2019-04-22 17:50:25

Why does a C program not work correctly in VS, although everything is fine in the online compiler?

The code:

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

// для задания 1.4 (посимвольное копирования из входного файла в выходной)
void getputChar(FILE* infile, FILE* outfile)
{
  char cha;

  cha = fgetc(infile);
  fputc(cha, outfile);
}

// для задания 1.4
int reverseOrder(FILE* infile, int pos, FILE* outfile)
{
  int npos = pos;
  char ch1;
  int count;
  int n;

  while (1) {
    ch1 = fgetc(infile);
    if (ch1 == '\n') {
      count = reverseOrder(infile, npos + 1, outfile) + 1;
      fseek(infile, pos, SEEK_SET);
      for (n = 0; n < count; ++n)
        getputChar(infile, outfile);
      fputc('\n', outfile);
      return count;
    }
    else if (ch1 == EOF) {
      if (npos - pos == 0)
        return 0;
      else {
        fseek(infile, pos, SEEK_SET);
        getputChar(infile, outfile);
        fputc('\n', outfile);
        return 1;
      }
    }
    else {
      npos++;
    }
  }
}

int main(int argc, char **argv)
{
  setlocale(LC_ALL, "Ru");
  FILE *file_ptr; // указатель на файл (задание 1.1)
  int N; // количество строк и символов в строках (задание 1.1)
  int count = 0; // для подсчета количества строк (задание 1.2)
  char ch; // для подсчета количества строк (задание 1.2)
  char text[50] = "0"; // строка для чтения из файла
  FILE *file_ptr1; // указатель на f2 (задание 1.4)
  int a; // для задания 1.3
  char tmp; // для задания 1.3
  FILE *file_ptr2; // вспомогательный файл для задания 1.3
  int c = 0; // для задания 1.4 (определение, какая строка считалась)

  file_ptr = fopen("D:\\f1.txt", "w+");
  file_ptr1 = fopen("D:\\f2.txt", "w+");
  file_ptr2 = fopen("D:\\f3.txt", "w+");

  if (file_ptr != NULL) {
    printf("Введите количество строк в файле и символов в них (не более 10): \n");
    scanf("%d", &N);

    if (N > 10) {
      do {
        printf("Нужно ввести число не более 10! Повторите ввод: \n");
        scanf("%d", &N);
      } while (N > 10);
    }

    printf("Введите строки не более %d символов.\n", N);

    for (int i = 0; i < N; i++)
    {
      printf("Введите %d-ю строку: \n", (i + 1));
      scanf("%s", text);
      if (strlen(text) > N) {
        do {
          printf("Нельзя вводить больше %d символов! Введите строку еще раз: \n", N);
          scanf("%s", text);
        } while (strlen(text) > N);
        fputs(text, file_ptr);
        fputs("\n", file_ptr);
      }
      else
      {
        fputs(text, file_ptr);
        fputs("\n", file_ptr);
      }
    }


    // вывод числа строк в файле (задание 1.2)
    fseek(file_ptr, 0, SEEK_SET);
    while ((ch = fgetc(file_ptr)) != EOF) {
      if (ch == '\n')
        ++count;
    }
    printf("Количество строк в файле: %d\n", count);


    // реверс строк в файле (задание 1.3)
    fseek(file_ptr, 0, SEEK_SET);
    while (fgets(text, 50, file_ptr)) {
      count = strlen(text) - 1;
      for (a = 0; a < count / 2; a++) {
        tmp = text[a];
        text[a] = text[count - 1 - a];
        text[count - 1 - a] = tmp;
      }
      fputs(text, file_ptr2);
    }
    // копирование из вспомогательного файла в исходный
    fseek(file_ptr, 0, SEEK_SET);
    fseek(file_ptr2, 0, SEEK_SET);
    if (file_ptr2 != NULL) {
      while (fgets(text, 50, file_ptr2)) {
        fputs(text, file_ptr);
      }
    }
    else {
      printf("Невозможно открыть файл f3\n");
      return 1;
    }


    // вывод в f2 (задание 1.4)
    if (file_ptr1 != NULL) {
      fseek(file_ptr, 0, SEEK_SET);
      fseek(file_ptr1, 0, SEEK_SET);
      reverseOrder(file_ptr, 0, file_ptr1);
    }
    else {
      printf("Невозможно открыть файл f2\n");
      return 1;
    }
    /*fseek(file_ptr, 0, SEEK_SET);
    if (file_ptr1 != NULL) {
      while (fgets(text, 50, file_ptr)) {
        c++;
        fseek(file_ptr1, strlen(text), SEEK_CUR);
        fputs(text[strlen(text) - c - 1], file_ptr1);
        fputs("\n", file_ptr1);
      }
    }
    else {
      printf("Невозможно открыть файл f2\n");
      return 1;
    }*/


    // вывод содержимого f2 на экран (задание 1.5)
    printf("Содержимое файла f2:\n");
    fseek(file_ptr1, 0, SEEK_SET);
    while (fgets(text, 50, file_ptr1)) {
      printf("%s", text);
    }

    fclose(file_ptr);
    fclose(file_ptr1);
    fclose(file_ptr2);
    _getch();
    return 0;
  }
  else {
    printf("Невозможно открыть файл f1\n");
    return 1;
  }
}

How VS outputs:
spoiler
k4Ys4Y6.jpg

How https://www.jdoodle.com/ outputs (as it should be):
spoiler
VHcsg1MuSWM.jpg

Answer the question

In order to leave comments, you need to log in

5 answer(s)
R
Roman, 2019-04-22
@ZIK1337

The online compiler compiles with GCC, and most likely on a Linux system.
In Visual Studio, the Visual C compiler and the Windows system.
On Windows, a line in text files ends with two characters - \r\n .
On Linux, a line ends with a single character, \n . When you write the \n
character to a text file , Windows automatically adds the \r character . When reading a text file, it is skipped. Accordingly, you get the wrong pos in reverseOrder for which fseek is done . considered manually.
There are two ways to fix this: either tell the system that the file is binary, or use ftell instead of manually calculating npos.

T
tsarevfs, 2019-04-22
@tsarevfs

C++ has the concept of undefined behavior. When you do something very wrong, the compiler can do whatever it wants, up to launching intercontinental ballistic missiles.
In your case, the incorrect behavior is reproduced locally, you're in luck. The studio contains a debugger that will allow you to step through the program and find the moment when everything goes wrong.

C
CityCat4, 2019-04-22
@CityCat4

Wangyu, that you will not receive an answer to this question :)
Why?
Because no one is interested in wading through another noob lab on streaming I / O or something else the same.

V
vanyamba-electronics, 2019-04-22
@vanyamba-electronics

I think they can help here .

R
res2001, 2019-04-22
@res2001

You have a bunch of file operations, any one can return an error. You don't have any error checking in your code.
If there were error checks, maybe that would help you.
In reverseOrder() - recursion is used, according to the text of the tasks, I did not understand at all where recursion could be applied there. Maybe there is an error somewhere.
In 1.3 you calculate count strangely - strlen() returns the number of characters already without considering the null character. Why are you still subtracting 1?
In general, your tasks are linear. I would slightly modify the solution, which would greatly simplify the code.
Namely - enter a string and immediately do all the processing and stuffing it into files. Then enter the next one and process it, and so on until the end.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question