我正在编写一个程序,该程序应该从文件中获取文本并按字母顺序排列所有单词,并在每个单词旁边写入它出现的行。我将所有内容打印到另一个文件时遇到问题。我将结果打印到控制台,但不知道如何将其打印到文件中。有人可以帮忙吗? 这是我的代码
#include <stdio.h>
#include <stdlib.h>
#include "string.h"
void help() {
printf("This program counts symbols and words in each line. \n"
" You have to write a name of the program, -i and input name, \n"
" and -o and output name, remember to put .txt after \n"
" input and output name and .exe after program name. \n "); // TODO
}
int CommandConsole(int argc, char *argv[], char limiter[]) {
int i;
for (i = 1; i < argc; i++) {
if (argv[i][0] == limiter[0] && argv[i][1] == limiter[1]) { //strcmp
break;
}
}
return i + 1;
}
typedef struct lineNode {
int line;
struct lineNode *right;
} lineNode_t;
typedef struct node {
char *word;
lineNode_t *lineNodeHead;
struct node *left, *right;
} node_t;
lineNode_t *insertLineCount(lineNode_t *line, int lineCount) {
if (line == NULL) {
if ((line = (lineNode_t *)malloc(sizeof(lineNode_t))) != NULL) {
line->right = NULL;
line->line = lineCount;
}
} else {
line->right = insertLineCount(line->right, lineCount);
}
return line;
}
node_t *inserttree(node_t *tree, char *currentWord, int lineCount) {
if (tree == NULL) {
if ((tree = (struct node *)malloc(sizeof(struct node))) != NULL) {
tree->left = NULL;
tree->right = NULL;
strcpy(tree->word, currentWord);
tree->lineNodeHead = insertLineCount(NULL, lineCount);
}
} else
if (strcmp(tree->word, currentWord) > 0) {
tree->left = inserttree(tree->left, currentWord, lineCount);
} else
if (strcmp(tree->word, currentWord) < 0) {
tree->right = inserttree(tree->right, currentWord, lineCount);
} else {
tree->lineNodeHead = insertLineCount(tree->lineNodeHead, lineCount);
}
return tree;
}
void freetree(struct node *tree) {
if (tree != NULL) {
free(tree->word);
freetree(tree->left);
freetree(tree->right);
free(tree);
}
}
void printLineCount(lineNode_t *line, FILE *fileout) {
while (line != NULL) {
printf("%d, ", line->line);
line = line->right;
}
printf("\n\n");
}
void printtree(struct node *tree, FILE *fileout) {
if (tree != NULL) {
printtree(tree->left, fileout);
printf("%s found in:\n", tree->word);
printLineCount(tree->lineNodeHead, fileout);
printtree(tree->right, fileout);
}
}
void freeTreeLine(struct node *tree) {
while (tree->lineNodeHead != NULL) {
struct node *aux = tree->lineNodeHead;
tree->lineNodeHead = tree->lineNodeHead->right;
free(aux);
}
}
void freeTree(struct node *tree) {
if (tree->left != NULL) {
freetree(tree->left);
}
if (tree->right != NULL) {
freetree(tree->right);
}
freeTreeLine(tree);
free(tree->word);
free(tree);
}
int main(int argc, char *argv[]) {
struct node *tree = NULL;
int letter = '\0';
char word[100];
int i = 0;
int lineCount = 0;
if (argc == 5) {
FILE *filein = fopen(argv[CommandConsole(argc, argv, "-i")], "r");
FILE *fileout = fopen(argv[CommandConsole(argc, argv, "-o")], "w");
if (filein != NULL) {
while ((letter = fgetc(filein)) != EOF && i < 99) {
if (isalnum(letter) == 1 || letter == 39) {
word[i] = letter;
word[++i] = '\0';
} else {
if (letter == '\n') {// new line
lineCount++;
}
tree = inserttree(tree, word, lineCount);
for (int j = 0; j < i; j++) {
//fputc(word[j], fileout);
word[j] = ' ';
}
i = 0;
}
}
// printtree(tree,fileout);
fclose(filein);
fclose(fileout);
} else {
printf("File error!\n");
}
} else {
help();
}
return 0;
}
答案 0 :(得分:0)
您应该在树形打印功能中使用printf
,而不是使用fprintf
:
void printLineCount(lineNode_t *line, FILE *fileout) {
while (line != NULL) {
fprintf(fileout, "%d, ", line->line);
line = line->right;
}
fprintf(fileout, "\n\n");
}
void printtree(struct node *tree, FILE *fileout) {
if (tree != NULL) {
printtree(tree->left, fileout);
fprintf(fileout, "%s found in:\n", tree->word);
printLineCount(tree->lineNodeHead, fileout);
printtree(tree->right, fileout);
}
}
此外,fprintf(fileout, "%s found in:\n", tree->word);
只应在tree->lineNodeHead
为NULL
的情况下执行。
另请注意:
isalnum(letter) == 1
不正确。 isalnum()
和<ctype.h>
中的其他字符类函数如果参数不是字母或数字则返回0
,如果参数不是非零。不要比较== 1
,只需撰写isalnum(letter)
。
你有2个函数:freeTree()
释放行号,freetree()
释放行号。前者称之为后者。这是不正确的,因为行号不会被释放到第一级以下。
不要对39
等ASCII值进行硬编码,而是使用字符常量'\''
。
答案 1 :(得分:0)
Finished code with some lovely comments in Polish!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "tree.h"
void help()
{
printf("This program shows You words in alphabetical order as well as in which lines they occur. \n You have to write a name of the program, -i and input name, \n and -o and output name, remember to put .txt after \n input and output name and .exe after program name. \n "); // TODO
}
int CommandConsole(int argc, char *argv[], char limiter[])
{
int i;
for (i = 1; i < argc; i++) {//przeleć wszystkie argumenty
if (argv[i][0] == limiter[0] && argv[i][1] == limiter[1]) //strcmp
{
break;
}
}
return i + 1;
}
typedef struct lineNode//lista z numerami kolejnych linii koljnego wyrazu (tego samego)
{
int line;//numer tej lini
struct lineNode *right;//wskaźnik na następny numer
}lineNode_t;
typedef struct node//jedno dżewo
{
char *word;//jakie slowo
lineNode_t *lineNodeHead;//wskaznik na liste z numerami kolejnych linii wyrazu tego slowa u gory
struct node *left, *right;//wskaznik na lewo i prawo w dżewie
}node_t;
lineNode_t *insertLineCount(lineNode_t *line, int lineCount) {//a dopierdol mu kolejną linie do listy linii
if (line != NULL) {//jeśli linia nie jest nullem to dopiero wtedy możesz się dostać do pola, wartości, czy jak chuj chcesz to nazywać struktury (w node to jest word, lineNodeHead, left i right
if (line->right == NULL)//sprawdzasz czy następna strzałka prowadzi do czegoś konkretnego czy nie ma następnej wartości
{
line->right = (lineNode_t *)malloc(sizeof(lineNode_t));//zaalokuj pamięć na kolejny element listy
//żeby nam nie wyjebało błędu to dwie linijki niżej
line->right->right = NULL;//musimy mu powiedzieć, że następny na nic nie wskazuje
line->right->line = lineCount;//musimy do nastepnego wpisać to linie o którą się tutaj rozchodzi
}
else {//następna strzałka prowadzi na coś, czyyyyyli...
line->right = insertLineCount(line->right, lineCount);//czyyyli sprawdzamy następna szczałke
}
}
else {//żadnej struktury ni ma, czyli ja tworzymy (Albo jak znajduje słowo po raz pierwszy, albo jak doszedł (hehe) do końca listy i musi dodać kolejńa linie w której jest słowo
line = (lineNode_t *)malloc(sizeof(lineNode_t));
line->right = NULL;//to masz opisane troche wyżej
line->line = lineCount;
}
return line;//zwracamy wartość żeby ten poprzedni z rekurencji wiedział o co cho
}
node_t *inserttree(node_t *tree, char *currentWord, int lineCount)
{
if (tree == NULL)//jeżeli dżewo nie istnieje LUB doszliśmy w rekurencji do końca dżewa (znaleźliśmy miejsce dla naszego słowa)
{
tree = (struct node *) malloc(sizeof(struct node)); //alokujemy pamięć na to to
tree->left = NULL;//skoro dopiero tworzymy, to on nic pod sobą ni ma
tree->right = NULL;
tree->word = malloc(sizeof(char)*(strlen(currentWord) + 1)); //alokujemy pamięć na słowo
strcpy(tree->word, currentWord);//kopiujemy słowo z naszej tablicy na wskaźnik który przed chwilą zaalokowaliśmy
tree->lineNodeHead = insertLineCount(NULL, lineCount); //trzeba przelecieć (ehehehehe) liste linii i wrzucić tam nową linie
}
else if (strcmp(tree->word, currentWord) > 0) {//tree->word byłoby przed currentWord w słowniku
tree->left = inserttree(tree->left, currentWord, lineCount);//czyli lecimy w lewo()
}
else if (strcmp(tree->word, currentWord) < 0) {//tree->word byłoby po currentWord w słowniku
tree->right = inserttree(tree->right, currentWord, lineCount);//czyli lecimy w prawo
}
else {//Doszliśmy (hehe) do momentu w którym nie może iść ani w lewo ani w prawo, bo słowa są te same !!!!!!!!!!!!1!1!!11!1111!!!1jedenjedenjedenascie
tree->lineNodeHead = insertLineCount(tree->lineNodeHead, lineCount);
}
return tree;//przypisaliśmy odpowiednie wartości no to caller musi wiedzieć co on ma sobie przypisać
}
//DRUKUJEMY KURWAAAAAAAAAAAAA!!!!!!!!!!!!!!!!!!!!!!!!
void printLineCount(lineNode_t *line, FILE *fileout) {
while (line != NULL) {//przeleć (ehehehehe) całą liste linii żeby ją wypisać
fprintf(fileout, "%d, ", line->line); //a se wypisze
line = line->right; //next please
}
fprintf(fileout, "\n\n");//a se entery wpisze żeby ładnie wyglądało
}
void printtree(struct node *tree, FILE *fileout)//Wydrukuj mi dżewo ziomek
{
if (tree != NULL)//przeleć (hehe (to już się robi nudne)) wszystkie elementy w dżewie
{
printtree(tree->left, fileout);//wydrukuj mi kurwa to co mam z lewej najpierw ziomek (alfabet, pamiętasz?)
fprintf(fileout, "%s found in:\n", tree->word);//O, wypisujemy teraz alfabetycznie
printLineCount(tree->lineNodeHead, fileout);//A teraz ile razy się powtara
printtree(tree->right, fileout);//No a teraz lecimy w prawo
}
}
void freeTreeLine(struct node *tree) {//zwalniamy kurwa linie
while (tree->lineNodeHead != NULL) {//masowe zwolnienia
lineNode_t *aux = tree->lineNodeHead; //zastępczy żebyśmy nie zgubili
tree->lineNodeHead = tree->lineNodeHead->right;//NASTĘPNY KURWA
free(aux);//zwolnij ten cośmy go nie zgublii bo tacy mądrzy my som
}
}
void freeTree(struct node *tree)//ZWALNIAMY KURWA DŻEWA
{
if (tree->left != NULL) {//Jeżeli już pod naszą lewą gałęzią nic nie ma...
freeTree(tree->left);
}
if (tree->right != NULL) {//...Jeżeli już pod naszą prawą gałęzią nic nie ma...
freeTree(tree->right);
}
freeTreeLine(tree);//...To możemy sami siebie zwolnić (żeby ci nad nami mogli siebie zwolnić)
free(tree->word);
free(tree);
}
int main(int argc, char * argv[]) {
struct node *tree = NULL;
char letter = '\0';
char word[100];//deklaracje no to wyjebane w sumie
int i = 0;
int lineCount = 1;
if (argc == 5) {
FILE *filein = fopen(argv[CommandConsole(argc, argv, "-i")], "r");//otwieranie plików to wyjebane
FILE *fileout = fopen(argv[CommandConsole(argc, argv, "-o")], "w");
if (filein != NULL) {//jeśli istnieje nasz plik wejścia
while ((letter = fgetc(filein)) != EOF && i < 99)//pobierz z pliku znak i sprawdź czy to nie koniec pliku albo czy słowo nie jest za długie
{
if (letter > 0 && letter < 256) {//jakieś błędy pliku? wyskakiwało letter = -30 i co wtedy masz zrobić? potnij się.
if (isalnum(letter) != 0) {//jeśli nasz znak to literka albo apostrof
word[i] = letter;//dodaj następny znak do naszego słowa
word[++i] = '\0';//NAJPIERW DODAJ JEDEN DO i, a później wpisz do tablicy '\0' (i++ by robiło na odwrót)
}
else {//jeśli nasze słowo się skończyło
if (letter == '\n') {// new line
lineCount++;
}
tree = inserttree(tree, word, lineCount);//wsadź (hehe) je w drzewo
i = 0;//resetujemy długość słowa
}
}
}//ok skońcyzliśmy wypełniać drzewo (lol)
if (tree != NULL) {//jeśli wgl je stworzyliśmy (bo może być pszypał i plik się otworzy ale jest pusty)
if (fileout != NULL) //jeśli nasz plik wyjściowy istnieje
printtree(tree, fileout);//wypisz
freeTree(tree);//no i zwolnij niezależnie cyz istnieje czyn nie
}
fclose(filein);//zamykamy pliki
fclose(fileout);
}
else {
printf("File error!\n");
}
}
else
{
help();
}
return 0;
}