似乎strncmp通常建议比strcmp,有什么优势?我认为这可能与安全有关.如果是这种情况,如果已知其中一个输入字符串是字面常量,它仍然适用"LiteralString"吗?
更新:
我的意思是在需要比较整个字符串的相同用户场景下,strncmp可以如下使用.我想知道它是否有意义.
strncmp(inputString, "LiternalString", strlen("LiternalString"));
Run Code Online (Sandbox Code Playgroud) 我很确定 glibc 是 gcc 的标准 C 库实现的名称。
但对于 LLVM/Clang,我不确定。我已经在谷歌上搜索过它是否带有整个标准 C 库的自己的实现,或者它们是否也使用 glibc。令人惊讶的是,我能找到的只是最近一篇讨论Google 正在考虑为 LLVM 编写新 libc 的文章。但不是那会取代什么。
即使在 LLVM/Clang 源代码库中,我也很有可能只是盲目或愚蠢,但我似乎找不到它。
明确地说,我只对 C 标准库感兴趣,而不是 C++ 标准库。我对研究它们printf对函数族的实现特别感兴趣。
有人可以告诉我在哪里可以找到 Clang 的 libc/标准 C 库实现或其源代码库吗?
在尝试实现 freopen()时,我在标准中提出了一条规范,据我所知,该规范实际上并未指定任何内容。
因此...freopen()将关闭流(忽略错误),清除其错误和 EOF 标志,重置宽方向,然后使用给定模式重新打开流。这已经很清楚了;这基本上是一个 fclose() / fopen()。即使它不是这样定义的,但很明显这就是我们的意图。
但是,我有两个关于setvbuf()可以对流执行的操作的问题 - 设置用户分配的缓冲区和/或更改缓冲区策略。
问题1.
1)freopen()预计会将事情恢复到默认状态,就像它实际调用过一样fopen()?或者无论用户在旧流上设置了什么,它都有望延续到新流中吗setvbuf()?这指的是缓冲存储器和缓冲策略,但这里的主要问题是缓冲存储器。
规范fclose()指定用户通过的与流关联的任何缓冲区都setvbuf()被取消关联,即现在可以free()由用户设置。
但freopen()仅指定它关闭与流关联的文件,而不是它fclose()关闭它。
那么,在 后freopen(),用户关联的缓冲区内存是否仍然与流关联?
问题2。
freopen()FILE可以想象,可以在调用时实际上与打开的文件没有关联的结构上使用(因为尝试关闭文件的错误将被忽略)。
该文件结构可能是先前打开的流,具有用户分配的缓冲区内存和缓冲区策略。是freopen()遵守这些设置,即将缓冲区内存/策略与“重新”打开的文件重新关联,还是将结构重新初始化为默认值,假设用户在先前访问文件free()后删除了缓冲区内存?fclose()
我的看法是。
看看第二个问题,我没有看到标准库能够可靠地确定FILE具有用户分配的缓冲内存的当前未打开的结构是否仍然“拥有”该缓冲内存,或者用户是否已经回收了该内存。(可以想象,该内存可能是本地的,即不是由malloc()/free()即使我愿意去那里处理的内存列表的一部分 - 这将非常不寻常地涉及标准库函数所期望的工作。)
缓冲政策的类似考虑。
因此,据我所知,唯一可靠的freopen()处理方法是将“与指定流关联的任何文件”的关闭处理为“真实” fclose(),并将缓冲内存/策略重新设置为默认值。
我的理解是否正确,或者 Q1 / Q2 是否有其他答案?
c standards standard-library language-lawyer c-standard-library
C 规范要求所有 C 程序都有 3 个开放的流可供它们使用:stdout, stdin, stderr.
用户可以根据需要使用这些流,例如:
fprintf(stdout, "lol");
fputs("oops", stderr);
fgets(buffer, 20, stdin);
Run Code Online (Sandbox Code Playgroud)
C 标准库中的一些函数隐式使用这些,例如:
printf("lol"); /* implicitly uses stdout */
puts("rofl"); /* implicitly uses stdout */
int c = getchar(buffer); /* implicitly uses stdin */
Run Code Online (Sandbox Code Playgroud)
stderr?stderr?C2x,7.21.9.2 fseek 函数:
概要
Run Code Online (Sandbox Code Playgroud)#include <stdio.h> int fseek(FILE *stream, long int offset, int whence);
为什么fseek有long int offset而不是long long int offset?
似乎在具有数据模型LLP64 或 ILP32 的操作系统(例如 Microsoft Windows)上2147483647(2 GB)可能不够。
我想检查一下代码。我已经搜索了我的 Mac、Stack Overflow 和互联网,但我找不到答案。也许他们不会将此代码放在 Mac 上。谁能让我直截了当?
使用嵌入式 C 项目。有库,包含文件等 - 用于微控制器。我不需要为主机和操作系统(Linux Mint 64 位)使用 GCC。按照惯例...
但是现在我正在尝试从 Github编译mspdebug项目——当然是使用 GCC。我在 make 一开始就收到一个错误:
mspdebug$ make
cc -DUSE_READLINE -O1 -Wall -Wno-char-subscripts -ggdb -I. -Isimio -Iformats -Itransport -Idrivers -Iutil -Iui -DLIB_DIR=\"/usr/local/lib/\" -o util/btree.o -c util/btree.c
util/btree.c:19:20: fatal error: assert.h: No such file or directory
#include <assert.h>
^
compilation terminated.
Run Code Online (Sandbox Code Playgroud)
我在所有可能的路径中搜索包含(我通过 gcc -v 命令获得了它们的列表) - 没有 assert.h 文件,以及 stdio.h 等等。除了虚拟框目录只有一个地方(GCC 不搜索包含的地方):/usr/lib/syslinux/com32/include
AFAIK,所有标准库和包含都与 GCC 一起安装。所以我尝试重新安装 GCC (4.8.4) - 没有任何变化。
为 GCC 提供所需的所有标准环境的正常方法是什么?
#include <cmath>
double log(double) {return 1.0;}
int main() {
log(1.0);
}
Run Code Online (Sandbox Code Playgroud)
假设函数log()in<cmath>是在全局命名空间中声明的(这实际上是未指定的,我们只是假设),那么它引用的函数与log()我们定义的函数相同。
那么这段代码是否违反了一个定义规则(参见这里,因为不需要诊断,这段代码可能会在某些编译器中编译,我们无法断言它是否正确)?
注意:经过最近的编辑,这不是以下内容的重复:C++ 中的一个定义规则究竟是什么?
c++ one-definition-rule c++-standard-library language-lawyer c-standard-library
通常,C 文件 I/O 是使用完成的,FILE*因为这是标准库函数都采用的。
在 C 中,也可以有一个const 指针,指针的地址不能改变(但它指向的值可以)。
我想知道这是否可以应用于FILE*,所以写了这个小程序来测试这个:
#include <stdio.h>
int main(void) {
FILE* const file = fopen("somefile.txt", "w");
if (file != NULL) {
fprintf(file, "%s\n", "So this works? That's just swell!");
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这可以很好地编译并使用 GCC 在 Ubuntu/Linux 16.04 上按预期工作(该文件包含我预期的字符串),但我不确定这个习语是否是一个好主意 - 该FILE类型在设计和处理上是不透明的是特定于实现的。
因为不能保证任何 C 库实现都不会尝试更改FILE指针的地址,所以在 C 中执行 I/O 时不使用这种方法是否更安全?
有件事总是让我困惑va_end()。我经常读到这不是一个实际的函数,而是一个预处理器宏。尽管这听起来像是一个无关紧要的细节,但它实际上可能会影响va_end()需要调用的位置。
问题很简单:是否需要在具有多个语句的可变参数函数中的va_end()每个语句之前调用?returnreturn
NULL以下示例中的可变参数函数具有返回第一个非参数的简单任务。return正如你所看到的,函数体中有三个语句。其中之一出现在 之后va_start()但之前va_end()。
这段代码正确吗?
#include <stdio.h>
#include <stdarg.h>
static const void * const FIRST_NON_NULL_END = (void *) "";
void * first_non_null (
const void * const ptr1,
...
) {
if (ptr1) {
return ptr1 == FIRST_NON_NULL_END ? NULL : (void *) ptr1;
}
void * retval;
va_list args;
va_start(args, ptr1);
do {
retval = va_arg(args, void *);
if (retval == FIRST_NON_NULL_END) {
/* …Run Code Online (Sandbox Code Playgroud)