Προς το περιεχόμενο

C - μπορώ να γράψω κατακόρυφα σε ένα αρχείο?


menmas

Προτεινόμενες αναρτήσεις

Δημοσ.

Hello!

 

εχω ένα αρχείο με πολλες ακολουθίες χαρακτήρων.

Θέλω να φτιάξω ένα αρχείο που να περιέχει τα ίδια στοιχεία ανάστροφα

 

ΠΧ

Το αρχείο έχει ABCDEF και θέλω το νέο αρχείο να περιέχει

A

B

C

D

E

F

 

Για αυτό σκέφτηκα μηπως μπορώ να γράψω κάθετα σε ένα αρχείο.

Γίνεται αυτό?Μπορείτε να μου πείτε μια καμιά ιδέα?

 

Ευχαριστώ!!

Δημοσ.

Φυσικά και γίνεται... μπορείς για κάθε χαρακτήρα που διαβάζεις από το αρχικό αρχείο, να τον γράφεις στο νέο προσθέτοντας ενα \n...

Δημοσ.
Φυσικά και γίνεται... μπορείς για κάθε χαρακτήρα που διαβάζεις από το αρχικό αρχείο, να τον γράφεις στο νέο προσθέτοντας ενα \n...

 

Το παραπάνω ισχύει αν υποτεθεί ότι το αρχείο έχει μόνο μια γραμμή (και άρα το αρχείο εξόδου θα έχει μόνο μια στήλη).

 

Διαφορετικά θα χρειστεί να χρησιμοποιήσεις fseek είτε για την ανάγνωση (και να κάνεις με τη "σειρά" τις εγγραφές), είτε για την εγγραφή (και να κάνεις με τη "σειρά" τις αναγνώσεις).

 

Τελευταίο ενδεχόμενο είναι να έχεις τη δυνατότητα να διαβάσεις όλο το αρχείο στη μνήμη, οπότε κάνεις την αναστροφή στη μνήμη και γράφεις το αποτέλεσμα πίσω στο αρχείο.

Δημοσ.

Γεια

 

Ναι το αρχείο μου δεν θα έχει μια μόνο στήλη, οπότε θα παίξω με fseek

Δυστυχώς δεν κατέχω και πολύ τη διαχείριση αρχείων. Θα ψάξω να δω τι πάιζει με την fseek και αν χρειαστώ θα ξανακαλέσω!!

 

Σας ευχαριστώ πολύ πάντως

Δημοσ.

Ενδιαφέρον θέμα ..

 

Μια σχετικά εύκολη αν και χρονοβόρα λύση (από άποψη επεξεργασία δεδομένων, μνήμης κτλ) είναι η δημιουργία ενός δισδιάστατου πίνακα (ptrVBuffer) στην μνήμη με ύψος ανάλογο εκείνο της μεγαλύτερης πρότασης του κειμένου μας (MaxWide) και πλάτος τον αριθμό των προτάσεων (LineCount) που θέλουμε να εισάγουμε σε αυτόν. Ύστερα φτάνει να αντιγράψουμε κάθε πρόταση (θεωρώ σαν πρόταση οτιδήποτε τερματίζει με \n) κάθετα στον πίνακα αυτόν αλλάζοντας στήλη ανά νέα πρόταση (Χ++). Ύστερα μπορούμε σχετικά απλά να εκτυπώσουμε τα αποτελέσματα στο STDOUT.

 

Ακολουθεί ο κώδικας αυτός γραμμένος σε C++ Builder 2009:

 

>
/*
* Print each line as vertical text by directx.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/* CodeGear C++ Builder compiler flags. */
#ifdef __BORLANDC__
#pragma hdrstop
#pragma argused
#endif

char** _Free(char**, int Row);

int main(void)
{
char *ptrBuffer =
		"Despite my most\n careful searches\n and investigations, \nI have never\n since been\n able to find the\n Rue d’Auseil.\nBut I am not\n wholly sorry; \neither for this or for\n the loss\n in undreamable\n abysses\n of the\n closely-written sheets \nwhich alone could\n have explained\n the music of\n Erich Zann.",
	 *ptrLine = NULL, *ptrBufferB = NULL;
int MaxWide = 0, LineCount = 0, Y, X;
FILE *fStream = NULL;

/* Store ptrLine because strtok is destructive. */
if((ptrBufferB = (char*)calloc(strlen(ptrBuffer) + 1, sizeof(char))) != NULL)
{
	strcpy(ptrBufferB, ptrBuffer);
	/* Find the widest line of the ptrBuffer and the buffer lines count. */
	if((ptrLine = strtok(ptrBufferB, "\n")) != NULL)
		do{
			if(strlen(ptrLine) > MaxWide)
				MaxWide = strlen(ptrLine);
			LineCount++;
		}while((ptrLine = strtok(NULL, "\n")) != NULL);
	/* Allocate a large enough buffer for vertical text. */
	char **ptrVBuffer = NULL;

	if((ptrVBuffer = (char**)calloc(MaxWide, sizeof(char*))) == NULL)
	{
		printf("Error because of calloc on MaxWide.\n");
		free(ptrVBuffer); free(ptrBufferB);
		return	1;
	}
	for(Y = 0; Y < MaxWide; Y++)
	{
		if((ptrVBuffer[Y] = (char*)malloc(LineCount * sizeof(char))) == NULL)
		{
			printf("Error because of calloc on LineCount.\n");
			_Free(ptrVBuffer, Y); free(ptrBufferB);
			return	1;
		}
		/* Init. ptrVBuffer[Y] with spaces (zeroes are ugly on stdout). */
		memset(ptrVBuffer[Y], ' ', LineCount * sizeof(char));
	}

	Y = X = 0;
	/* Start transforming horizontial to vertical text. */
	if((ptrLine = strtok(ptrBuffer, "\n")) != NULL)
	{
		do{
			for(Y = 0; Y < MaxWide && Y < strlen(ptrLine); Y++)
				ptrVBuffer[Y][X] = ptrLine[Y];
			X++;
		}while((ptrLine = strtok(NULL, "\n")) != NULL);
	}
	/* Write transformed text to stdout. */
	for(Y = 0; Y < MaxWide; Y++)
	{
		for(int X = 0; X < LineCount; X++)
			putchar(ptrVBuffer[Y][X]);
		putchar('\n');
	}
	/* Free local resources. */
	_Free(ptrVBuffer, MaxWide - 1);
	free(ptrBufferB);
}
else
	printf("Error because of calloc on ptrBufferB.\n");

printf("\nPress Enter to exit..");
getchar();

return	0;
}

char** _Free(char **ptr2DArray, int Row)
{
/* Free this 2D array. */
for(; Row >= 0; Row--)
	free(ptr2DArray[Row]);
free(ptr2DArray);
return	(ptr2DArray = NULL);
}

 

Ο κώδικας έχει δοκιμασθεί με μικρό αριθμό εισαγωγών (ptrBuffer) σε CodeGear C++ Builder 2009 και μπορεί να περιέχει σφάλματα ή άλλες αβλεψίες.

 

ΕΙΣΟΔΟΣ

Despite my most\n careful searches\n and investigations, \nI have never\n since been\n able to find the\n Rue d’Auseil.\nBut I am not\n wholly sorry; \neither for this or for\n the loss\n in undreamable\n abysses\n of the\n closely-written sheets \nwhich alone could\n have explained\n the music of\n Erich Zann.

 

ΕΞΟΔΟΣ

>
D  I   B e     w
eca saRuwitiaochhtE
sanhibuththnbfliahr
prdanle ohe y ocvei
ie vce Ile ustshe c
tfiee d lrlnshe  mh
eun  tΤay odeelaeu
lvnboAm fsrs ylxsZ
m eee u sose  -opia
yssvefsnor a  wnlcn
etenieor  m  rea n
mair nitrt a  i io.
org  dl yh b  tcnf
sca   . ;i l  toe
tht  t   s e  eud
ei  h        nl
so  e   o     d
 n      r    s
 s           h
 ,      f    e
        o    e
        r    t
             s


Press Enter to exit..

 

Καλή τύχη!!

Δημοσ.

Να μια γρήγορη λύση χωρίς πολλά resources για το παραπάνω που κάνει ο Directx.

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

int main(void) {

 char buf[bUFSIZ] = {0};
 size_t n, i, j, k;
 struct { size_t size, pos; } *m;

 fread(buf, 1, BUFSIZ - 1, stdin);
 n = strlen(buf);
 for(i = j = 0; j < n;
     j += strcspn(buf + j, "\n") + 1, i++);
 assert(i && (m = malloc(sizeof *m * i)));
 for(j = 0; j < i; j++) {
   m[j].pos = (j > 0) ? m[j-1].pos + m[j-1].size + 1 : 0;
   m[j].size = strcspn(buf + m[j].pos, "\n");
 }
 for(j = n = 0; j < i; j++)
   n = (m[j].size > n) ? m[j].size : n;
 for(j = 0; j < n*i; j++) {
   k = j % i;
   if(k == 0 && j != 0) putchar('\n');
   if(m[k].size*i > j)
     putchar(buf[m[k].pos + j/i]);
   else
     putchar(' ');
 }
 putchar('\n');
 free(m);

 return 0;
}

Αρχειοθετημένο

Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.

  • Δημιουργία νέου...