在C语言中,在原本非空的文件中,插入一行数据
时间: 2024-03-23 12:41:25 浏览: 160
在C语言中,在原本非空的文件中插入一行数据,可以按照以下步骤进行操作:
1. 打开文件,获取文件指针
使用fopen函数打开文件,指定打开方式为“读写”(r+)或“追加”(a+),并返回一个文件指针。
2. 移动文件指针
使用fseek函数将文件指针移动到需要插入数据的位置,可以使用SEEK_SET、SEEK_CUR、SEEK_END三个宏定义指定偏移量的基准位置。
3. 写入数据
使用fprintf函数将数据写入文件中,格式为“%s”或“%d”。
4. 关闭文件
使用fclose函数关闭文件,释放文件指针。
示例代码如下:
```c
#include <stdio.h>
int main() {
FILE *fp;
char str[] = "Hello, World!";
int num = 12345;
// 打开文件
fp = fopen("data.txt", "r+");
// 移动文件指针
fseek(fp, 10, SEEK_SET); // 将文件指针移动到第11个字符后面
// 写入数据
fprintf(fp, "%s\n", str);
fprintf(fp, "%d\n", num);
// 关闭文件
fclose(fp);
return 0;
}
```
运行该程序后,会在文件“data.txt”中第11个字符后面插入一行数据,“Hello, World!”和“12345”。
相关问题
写出c语言代码:给一非空的单词列表,返回前 k 个出现次数最多的单词。 返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率,按字母顺序排序。 输入:第1行为k值,第2行单词列表,单词列表以end结尾,end不属于单词列表中的单词。 2 i love leetcode i love coding end 输出: i love
好的,下面是具体的 C 语言代码实现:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LEN 1000
// 定义哈希表结构体
typedef struct {
char* word;
int count;
} Node;
// 定义优先队列结构体
typedef struct {
Node** data;
int size;
int capacity;
} PriorityQueue;
// 初始化优先队列
void initPriorityQueue(PriorityQueue* pq, int capacity) {
pq->data = (Node**)malloc(sizeof(Node*) * capacity);
pq->size = 0;
pq->capacity = capacity;
}
// 向优先队列中插入一个元素
void insert(PriorityQueue* pq, Node* node) {
if (pq->size == pq->capacity) return;
pq->data[pq->size++] = node;
int i = pq->size - 1;
while (i > 0) {
int parent = (i - 1) / 2;
if (pq->data[i]->count > pq->data[parent]->count ||
(pq->data[i]->count == pq->data[parent]->count &&
strcmp(pq->data[i]->word, pq->data[parent]->word) < 0)) {
Node* tmp = pq->data[i];
pq->data[i] = pq->data[parent];
pq->data[parent] = tmp;
} else {
break;
}
i = parent;
}
}
// 从优先队列中取出一个元素
Node* pop(PriorityQueue* pq) {
if (pq->size == 0) return NULL;
Node* ret = pq->data[0];
pq->data[0] = pq->data[--pq->size];
int i = 0;
while (i * 2 + 1 < pq->size) {
int left = i * 2 + 1;
int right = i * 2 + 2;
int maxIdx = i;
if (pq->data[left]->count > pq->data[maxIdx]->count ||
(pq->data[left]->count == pq->data[maxIdx]->count &&
strcmp(pq->data[left]->word, pq->data[maxIdx]->word) < 0)) {
maxIdx = left;
}
if (right < pq->size &&
(pq->data[right]->count > pq->data[maxIdx]->count ||
(pq->data[right]->count == pq->data[maxIdx]->count &&
strcmp(pq->data[right]->word, pq->data[maxIdx]->word) < 0))) {
maxIdx = right;
}
if (maxIdx != i) {
Node* tmp = pq->data[i];
pq->data[i] = pq->data[maxIdx];
pq->data[maxIdx] = tmp;
} else {
break;
}
i = maxIdx;
}
return ret;
}
// 释放优先队列
void freePriorityQueue(PriorityQueue* pq) {
free(pq->data);
}
// 哈希函数
int hash(char* word) {
int hash = 0;
for (int i = 0; i < strlen(word); i++) {
hash = hash * 31 + word[i];
}
return hash;
}
// 初始化哈希表
void initHashTable(Node** hashTable, int size) {
for (int i = 0; i < size; i++) {
hashTable[i] = NULL;
}
}
// 在哈希表中查找单词
Node* find(Node** hashTable, int size, char* word) {
int h = hash(word) % size;
Node* cur = hashTable[h];
while (cur != NULL && strcmp(cur->word, word) != 0) {
cur = cur->next;
}
return cur;
}
// 向哈希表中插入一个单词
void insertToHashTable(Node** hashTable, int size, char* word) {
int h = hash(word) % size;
Node* cur = hashTable[h];
while (cur != NULL) {
if (strcmp(cur->word, word) == 0) {
cur->count++;
return;
}
cur = cur->next;
}
Node* node = (Node*)malloc(sizeof(Node));
node->word = (char*)malloc(sizeof(char) * (strlen(word) + 1));
strcpy(node->word, word);
node->count = 1;
node->next = hashTable[h];
hashTable[h] = node;
}
// 统计单词出现次数并放入优先队列中
void countWords(Node** hashTable, int size, PriorityQueue* pq) {
for (int i = 0; i < size; i++) {
Node* cur = hashTable[i];
while (cur != NULL) {
insert(pq, cur);
cur = cur->next;
}
}
}
int main() {
int k;
scanf("%d", &k);
char word[MAX_LEN];
Node* hashTable[100000] = {NULL};
while (scanf("%s", word) != EOF && strcmp(word, "end") != 0) {
insertToHashTable(hashTable, 100000, word);
}
PriorityQueue pq;
initPriorityQueue(&pq, 100000);
countWords(hashTable, 100000, &pq);
for (int i = 0; i < k; i++) {
Node* node = pop(&pq);
if (node != NULL) {
printf("%s\n", node->word);
}
}
freePriorityQueue(&pq);
for (int i = 0; i < 100000; i++) {
Node* cur = hashTable[i];
while (cur != NULL) {
Node* tmp = cur;
cur = cur->next;
free(tmp->word);
free(tmp);
}
}
return 0;
}
```
以上代码使用了哈希表和优先队列两个数据结构来实现题目需求,具体实现细节可以看注释。
问题描还 文学研究人员需要统计某篇英文小说中某些形容词的出现次数和位置。试写--个实现这--目标的 文字统计系统,称为“文学研究助手”。 基本要求 英文小说存于一个文本文件中。待统计的词汇集合要一次输 入完毕,即统计工作必须在程序的一 次运行之后就全部完成。程序的输出结果是每个词的出现次数和出现位置的行号,格式自行设计。 测试数据 以源程序模拟英文小说,编程语言保留字集作为待统计的词汇集。 实现提示 设小说非空且以文件形式存放,其中的词汇一律不跨行。这样,每读入-行,就统计每个词在这 行中的出现次数和出现位置的行号,后者可以用链表存储。若某行中出现了不止一-次,不必存多个相 同的行号。数据结构采用二维链表,单词结点链接成一个链表,每个单词的行号组成- -个链表,单词 结占作为行号链表的头结占。用c语言
实现这个文学研究助手可以分为以下几个步骤:
1. 读入小说文本文件,将其存储到内存中。
2. 读入待统计的词汇集合,将其存储到内存中。
3. 逐行扫描小说文本,统计每个词汇在该行中的出现次数和出现位置的行号,并将结果存储到相应的数据结构中。
4. 输出每个词汇的出现次数和出现位置的行号。
下面是一个可能的实现:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_WORD_LEN 50 // 定义单词的最大长度
#define MAX_LINE_LEN 1000 // 定义行的最大长度
// 定义单词节点
typedef struct word_node {
char word[MAX_WORD_LEN]; // 单词
struct line_node *lines; // 行号链表
struct word_node *next; // 下一个单词
} word_node;
// 定义行号节点
typedef struct line_node {
int line_num; // 行号
struct line_node *next; // 下一个行号
} line_node;
// 统计单词出现次数和出现位置的函数
void count_words(char *filename, char **words, int num_words, word_node **word_list) {
FILE *fp;
char line[MAX_LINE_LEN];
int line_num = 0; // 记录当前行号
// 打开文件
fp = fopen(filename, "r");
if (fp == NULL) {
printf("Error opening file.\n");
exit(1);
}
// 逐行扫描文件
while (fgets(line, MAX_LINE_LEN, fp) != NULL) {
line_num++;
// 将行末的换行符去掉
if (line[strlen(line)-1] == '\n') {
line[strlen(line)-1] = '\0';
}
// 统计单词在该行中的出现次数和出现位置的行号
char *token = strtok(line, " ");
while (token != NULL) {
for (int i = 0; i < num_words; i++) {
if (strcmp(token, words[i]) == 0) {
// 找到了一个待统计的单词
word_node *word_ptr = *word_list;
word_node *prev_word_ptr = NULL;
while (word_ptr != NULL && strcmp(word_ptr->word, token) != 0) {
prev_word_ptr = word_ptr;
word_ptr = word_ptr->next;
}
if (word_ptr == NULL) {
// 没有找到该单词,需要创建新的单词节点并插入到单词链表中
word_ptr = (word_node *) malloc(sizeof(word_node));
strcpy(word_ptr->word, token);
word_ptr->lines = NULL;
word_ptr->next = NULL;
if (prev_word_ptr == NULL) {
// 插入到单词链表的头部
*word_list = word_ptr;
} else {
// 插入到单词链表的中间或尾部
prev_word_ptr->next = word_ptr;
}
}
// 将行号插入到该单词的行号链表中
line_node *line_ptr = word_ptr->lines;
line_node *prev_line_ptr = NULL;
while (line_ptr != NULL && line_ptr->line_num != line_num) {
prev_line_ptr = line_ptr;
line_ptr = line_ptr->next;
}
if (line_ptr == NULL) {
// 没有找到该行号,需要创建新的行号节点并插入到行号链表中
line_ptr = (line_node *) malloc(sizeof(line_node));
line_ptr->line_num = line_num;
line_ptr->next = NULL;
if (prev_line_ptr == NULL) {
// 插入到行号链表的头部
word_ptr->lines = line_ptr;
} else {
// 插入到行号链表的中间或尾部
prev_line_ptr->next = line_ptr;
}
}
}
}
token = strtok(NULL, " ");
}
}
// 关闭文件
fclose(fp);
}
// 输出单词出现次数和出现位置的函数
void print_words(word_node *word_list) {
word_node *word_ptr = word_list;
while (word_ptr != NULL) {
printf("%s: ", word_ptr->word);
line_node *line_ptr = word_ptr->lines;
while (line_ptr != NULL) {
printf("%d ", line_ptr->line_num);
line_ptr = line_ptr->next;
}
printf("(%d)\n", line_ptr == NULL ? 0 : 1); // 输出出现次数
word_ptr = word_ptr->next;
}
}
int main() {
char *filename = "novel.txt";
char *words[] = {"int", "char", "float", "double", "if", "else", "while", "for", "switch", "case", "break", "continue", "return"};
int num_words = sizeof(words) / sizeof(char *);
word_node *word_list = NULL;
count_words(filename, words, num_words, &word_list);
print_words(word_list);
return 0;
}
```
在这个程序中,我们定义了两个数据结构:单词节点和行号节点。单词节点包含单词本身、行号链表以及指向下一个单词的指针;行号节点包含行号本身以及指向下一个行号的指针。
在统计单词出现次数和出现位置时,我们使用了一个二维链表的结构,即单词节点链接成一个链表,每个单词的行号组成一个链表,单词节点作为行号链表的头节点。这样可以方便地统计每个单词在哪些行出现过,并输出出现次数和出现位置的行号。
阅读全文