-4

How to read 2 lines from a file at a time, then use pointers to alternately merge two line into one in C.

Sample input:

ABCDE
PQRSTFG
acegikmoqsuwyz
bdfhjlnprtvx

Ouput:

APBQCRDSETFG
abcdefghijklmnopqrstuvwxyz
Thien Tao
  • 1
  • 1
  • 1
    where does the `P` come from?! What's the logic? – Antti Haapala -- Слава Україні Mar 20 '19 at 18:02
  • @AnttiHaapala it's probably a typo (input should be `...DE PQ...` not `...DEP Q...` – jhnc Mar 20 '19 at 18:11
  • I would take a look at this question, and see if using the `getline` function would help: https://stackoverflow.com/q/3501338/1212725 – bruceg Mar 20 '19 at 18:22
  • I don't think the problem is unclear, as already said there is just a typo in the result for ABCDEP and QRSTFG producing AQBRCSDTEFPG rather than APBQCRDSETFG. It would have been better if the PO had given a (beginning of) proposal, however I put a proposal in my answer. – bruno Mar 20 '19 at 19:21
  • @bruno: The problem seems to be clear.. but the question is kind of "give me tech codes": there are at least two separate subtasks - reading the file by 2 lines and "merging" these lines - but the asker didn't show any code which demonstrates his level of C knowledge. – Tsyvarev Mar 20 '19 at 20:52

1 Answers1

1

A proposal :

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

char * readLine(ssize_t * ln)
{
  char * lineptr = NULL;
  size_t n = 0;

  *ln = getline(&lineptr, &n, stdin);

  if (*ln <= 0) {
    if (lineptr != NULL)
      free(lineptr);
    return NULL;
  }

  if (lineptr[*ln - 1] == '\n')
    lineptr[--*ln] = 0;

  return lineptr;
}

int main()
{
  size_t sz = 0;
  char ** lines = NULL;

  for (;;) {
    ssize_t n1;
    char * l1 = readLine(&n1);

    if (l1 == NULL)
      break;

    ssize_t n2;
    char * l2 = readLine(&n2);
    char * l;

    if (l2 == NULL) {
      /* consider the second line is empty if missing */
      l = l1;
    }
    else {
      l = malloc(n1 + n2 + 1);

      if (l == NULL) {
        fprintf(stderr, "not enough memory\n");
        return -1;
      }

      char * p1 = l1;
      char * p2 = l2;
      char * p = l;

      for (;;) {
        if (! *p1) {
          strcpy(p, p2);
          break;
        }
        *p++ = *p1++;
        if (! *p2) {
          strcpy(p, p1);
          break;
        }
        *p++ = *p2++;
      }
      free(l1);
      free(l2);
    }

    /* realloc for more than just 1 additional entry if lot of lines to manage */
    lines = realloc(lines, ++sz * sizeof(char *));
    if (lines == NULL) {
      fprintf(stderr, "not enough memory\n");
      return -1;
    }
    lines[sz - 1] = l;
  }

  /* debug and free */
  for (size_t i = 0; i != sz; ++i) {
    puts(lines[i]);
    free(lines[i]);
  }

  free(lines);
}

Compilation and execution :

pi@raspberrypi:/tmp $ gcc -pedantic -Wextra l.c
pi@raspberrypi:/tmp $ cat f
ABCDEP
QRSTFG
acegikmoqsuwyz
bdfhjlnprtvx
pi@raspberrypi:/tmp $ ./a.out < f
AQBRCSDTEFPG
abcdefghijklmnopqrstuvwxyz

Execution under valgrind :

pi@raspberrypi:/tmp $ valgrind ./a.out < f
==14583== Memcheck, a memory error detector
==14583== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==14583== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==14583== Command: ./a.out
==14583== 
AQBRCSDTEFPG
abcdefghijklmnopqrstuvwxyz
==14583== 
==14583== HEAP SUMMARY:
==14583==     in use at exit: 0 bytes in 0 blocks
==14583==   total heap usage: 11 allocs, 11 frees, 5,772 bytes allocated
==14583== 
==14583== All heap blocks were freed -- no leaks are possible
==14583== 
==14583== For counts of detected and suppressed errors, rerun with: -v
==14583== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)
bruno
  • 32,421
  • 7
  • 25
  • 37