- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有这个 C 作业,在这个特定点上我有点挣扎。我有一些 C 语言背景,但指针和动态内存管理仍然让我很困惑。
作业要求我们编写一个程序来模拟 UNIX 中“uniq”命令/过滤器的行为。
但是我遇到的问题是C库函数getline或getdelim(我们需要根据实现规范使用这些函数)。
根据规范,用户输入可能包含任意数量的行,并且每行可能具有任意长度(编译时未知)。
问题是,while 循环的以下行 while (cap = getdelim(stream.linesArray, size, '\n', stdin))
当我这样保留它时,会以某种方式编译并“工作”。我的意思是,当我执行程序时,我在每行输入任意数量的任意长度的行,并且程序不会崩溃 - 但它会一直循环,除非我停止程序执行(无论这些行是否正确存储)在“char **linesArray; ”中是一个不同的故事,我不确定。
我希望能够做类似的事情 while ((cap = getdelim(stream.linesArray, size, '\n', stdin)) && (cap != -1))
这样,当 getdelim 在某些行(除了 EOF 或\n 之外)没有读取任何字符时(也就是用户第一次输入空行时),程序将停止从 stdin 获取更多行。(然后通过 getdelim 打印存储在 stream.linesArray 中的行)。
问题是,当我执行程序时,如果我进行了上面提到的更改,程序会给我“段错误”,坦率地说,我不知道为什么以及应该如何解决这个问题(我尝试做一些事情)说了很多次都没有用)。
供引用:
https://pubs.opengroup.org/onlinepubs/9699919799/functions/getdelim.html
https://en.cppreference.com/w/c/experimental/dynamic/getline
http://man7.org/linux/man-pages/man3/getline.3.html
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DEFAULT_SIZE 20
typedef unsigned long long int ull_int;
typedef struct uniqStream
{
char **linesArray;
ull_int lineIndex;
} uniq;
int main()
{
uniq stream = { malloc(DEFAULT_SIZE * sizeof(char)), 0 };
ull_int cap, i = 0;
size_t *size = 0;
while ((cap = getdelim(stream.linesArray, size, '\n', stdin))) //&& (cap != -1))
{
stream.lineIndex = i;
//if (cap == -1) { break; }
//print("%s", stream.linesArray[i]);
++i;
if (i == sizeof(stream.linesArray))
{
stream.linesArray = realloc(stream.linesArray, (2 * sizeof(stream.linesArray)));
}
}
ull_int j;
for (j = 0; j < i; ++j)
{
printf("%s\n", stream.linesArray[j]);
}
free(stream.linesArray);
return 0;
}
最佳答案
好的,意图很明确 - 使用 getdelim
将行存储在数组中。 getline
本身使用动态分配。 manual说的很清楚:
getline() reads an entire line from stream, storing the address of the buffer containing the text into *lineptr. The buffer is null-terminated and includes the newline character, if one was found.
getline()
“将缓冲区的地址存储到*lineptr”。所以lineptr
必须是指向 char *
的有效指针变量(读两遍)。
*lineptr and *n will be updated to reflect the buffer address and allocated size respectively.
还有n
需要是一个指向 size_t
的有效(!)指针变量,因此函数可以更新它。
另请注意 lineptr
缓冲区:
This buffer should be freed by the user program even if getline() failed.
那么我们该怎么办呢?我们需要一个指向字符串数组的指针数组。因为我不喜欢成为三星级程序员,所以我使用结构。我稍微修改了你的代码,添加了一些检查。对不起,我不喜欢 typedef,所以我不使用它们。更名为uniq
至struct lines_s
:
#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
struct line_s {
char *line;
size_t len;
};
struct lines_s {
struct line_s *lines;
size_t cnt;
};
int main() {
struct lines_s lines = { NULL, 0 };
// loop breaks on error of feof(stdin)
while (1) {
char *line = NULL;
size_t size = 0;
// we pass a pointer to a `char*` variable
// and a pointer to `size_t` variable
// `getdelim` will update the variables inside it
// the initial values are NULL and 0
ssize_t ret = getdelim(&line, &size, '\n', stdin);
if (ret < 0) {
// check for EOF
if (feof(stdin)) {
// EOF found - break
break;
}
fprintf(stderr, "getdelim error %zd!\n", ret);
abort();
}
// new line was read - add it to out container "lines"
// always handle realloc separately
void *ptr = realloc(lines.lines, sizeof(*lines.lines) * (lines.cnt + 1));
if (ptr == NULL) {
// note that lines.lines is still a valid pointer here
fprintf(stderr, "Out of memory\n");
abort();
}
lines.lines = ptr;
lines.lines[lines.cnt].line = line;
lines.lines[lines.cnt].len = size;
lines.cnt += 1;
// break if the line is "stop"
if (strcmp("stop\n", lines.lines[lines.cnt - 1].line) == 0) {
break;
}
}
// iterate over lines
for (size_t i = 0; i < lines.cnt; ++i) {
// note that the line has a newline in it
// so no additional is needed in this printf
printf("line %zu is %s", i, lines.lines[i].line);
}
// getdelim returns dynamically allocated strings
// we need to free them
for (size_t i = 0; i < lines.cnt; ++i) {
free(lines.lines[i].line);
}
free(lines.lines);
}
对于这样的输入:
line1 line1
line2 line2
stop
将输出:
line 0 is line1 line1
line 1 is line2 line2
line 2 is stop
在 onlinegdb 上测试.
注释:
if (i == sizeof(stream.linesArray))
sizeof
不会神奇地存储数组的大小。 sizeof(stream.linesArray)
只是 sizeof(char**)
只是一个指针的 sizeof 。它通常是 4 或 8 字节,具体取决于 32 位还是 64 位架构。
uniq stream = { malloc(DEFAULT_SIZE * sizeof(char)),
-stream.linesArray
是 char**
多变的。所以如果你想要一个指向 char
的指针数组,您应该为指针分配内存 malloc(DEFAULT_SIZE * sizeof(char*))
.
typedef unsigned long long int ull_int;
size_t
type 如果表示数组大小或 sizeof(variable) 的类型。 ssize_t
有时在 posix api 中使用来返回大小和错误状态。使用这些变量,无需输入 unsigned long long
.ull_int cap
cap = getdelim
- cap 未签名,它永远不会是 cap != 1
.关于c - 我应该如何修复这个有趣的 getdelim/getline (动态内存分配)错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55505716/
我将一个 div 设置为 100% 宽度,当以 1024 分辨率查看页面时,宽度应从 100% 变为 1000px,我让它与@media 查询一起正常工作,并且在 FF、safari chrome 上
希望有人能帮助我,我已经被困了几天了。 将我的 Domino 服务器更新到 9.01 Fix 3 后,我在 javascript 控制台上不断收到错误消息: TypeError: this.edito
我们正在使用一个基于RMI的java应用程序。当我们运行应用程序时,即使应用程序处于理想阶段,内存使用量仍然不断增加。我们主要使用Vector和散列图数据结构。如何最大限度地减少java内存使用/修复
概述 Internet Download Manager (IDM)是最流行的 Windows 下载管理器。如果你平时工作中使用过IDM,您会惊叹 IDM 下载文件的速度有多快。IDM
当我打开 brave 浏览器时,会打开一个窗口(如下所示)。它并没有真正干扰浏览器的处理。但令人担忧的是为什么这种情况一直发生...... Error On Opening Brave Browser
这是我今天在求职面试中被问到的一个问题: 看下面的代码: int n=20; for (int i =0; i
我不小心删除了/opt/local/bin/perl5.8.9 ,这似乎是 macports 编译的 perl 的主要二进制文件。 现在我有很多取决于 perl5 的端口,但不想卸载并重新安装所有端口
>>>flip fix (0 :: Int) (\a b -> putStrLn "abc") Output: "abc" 这是使用翻转修复的简化版本。 我在一些 YouTube 视频中看到了这种使用
这个问题已经有答案了: How can I fix 'android.os.NetworkOnMainThreadException'? (64 个回答) 已关闭 3 年前。 我在 Android 应
def main(): cash = float(input("How much money: ")) coins = 0 def changeCounter(n): whil
前一周我遇到了类似的问题,查询需要永远运行。在编写此查询时,我尝试应用从其他查询中学到的一些知识,但执行起来需要很长时间。 运行查询的两个单独部分时,每个部分需要 2 分钟才能完成,这是可以接受的,但
下午,我的 CSS 有问题。第三个下拉菜单放错了,我没有解决办法。 这是我想要的: 之前: http://i53.tinypic.com/2qu85z8.png 之后: http://i51.tiny
更新方法: override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingS
我知道这是一个很多人都遇到过的问题,但我不熟悉 Less 并且是 Bootstrap 的新手,我正在寻找一种全 CSS 解决方案来防止我的导航栏折叠到 768 像素以下:
在我的布局中,我创建了以下 jsfiddle 托管的可调整大小的粘性页脚。但是,在调整大小时它与内容重叠。有没有办法让它在所有浏览器上都能响应? http://jsfiddle.net/9aLc0mg
我想要实现的目标 racer-offset 是为了让用户可以设置图像可以以 px 为单位移动多远。偏移量管理偏移量。 Speed-racer 告诉我们图像在滚动过程中移动的速度。我的问题是它不会停止。
我有一个简单的自动换行函数,它接受一个长字符串作为输入,然后将该字符串分成更小的字符串,并将它们添加到一个数组中,以便稍后输出。现在最后一两个字没有输出。这是主要问题。但是,我还想改进功能。我知道这有
我试图在使用每个 slider 之前禁用“下一步”按钮,我不确定为什么在单击不再是 class="not-clicked"的同一个 slider 时取消禁用该按钮. JSFiddle: (这里看起来有
这个问题已经有答案了: What is a NullPointerException, and how do I fix it? (12 个回答) 已关闭 8 年前。 如何让程序输出所有信息? IT
On this page ,在“生活”下有一个带有自动生成的子菜单的菜单。子菜单存在一些问题(它会闪烁并改变大小——如果你滚动它就会看到)。我需要以某种方式覆盖它当前正在读取的 css 并使其统一。
我是一名优秀的程序员,十分优秀!