Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何从该文件中读取值_C++_File Io - Fatal编程技术网

C++ 如何从该文件中读取值

C++ 如何从该文件中读取值,c++,file-io,C++,File Io,因此,我有以下代码: int main() { FILE *file; file = fopen("fonts.dat", "rb"); if (file == NULL) return 1; char readLineBuffer[200]; if(readLineBuffer == NULL) { return 1; } if(readLineBuffer == 0) { return 1; } while (fg

因此,我有以下代码:

int main()
{
    FILE *file;
    file = fopen("fonts.dat", "rb");
    if (file == NULL)
        return 1;

    char readLineBuffer[200];

    if(readLineBuffer == NULL) { return 1; }
    if(readLineBuffer == 0) { return 1; }

    while (fgets(readLineBuffer, 200, file) != NULL)
    {
        readLineBuffer[strcspn(readLineBuffer, "\n")] = '\0';
        //if (readLineBuffer[0] == '\0' || readLineBuffer[0] == '#') {continue;}
        for(int i=0; readLineBuffer[i]!=00; i++)
        {
            if (readLineBuffer[i]=='#')
            {
                readLineBuffer[i] = 00;
                break;
            }
        }
        puts(readLineBuffer);
    }

    fclose(file);

    system("PAUSE");
    return 0;
}
它删除以
#
开头的注释行


但是我怎样才能从[FONT_ID]这样的文件中读取数据并将其存储到一个变量中,以便在其他代码中使用呢?

这段代码中有很多内容表明您很难掌握C/C++,或者您一直在从其他程序员/语言那里学习不好的习惯

FILE *file;
file = fopen("fonts.dat", "rb");
尽可能避免将声明和赋值分开。你说这是一个文本文件,所以你不需要以“二进制”模式打开它。以二进制读取意味着您将不得不担心不同的行尾类型。在文本模式下打开它,操作系统/libc将为您进行翻译,这样行的结尾就可以像应该的那样神奇地“\n”

char readLineBuffer[200];

if(readLineBuffer == NULL) { return 1; }
if(readLineBuffer == 0) { return 1; }
首先,您刚才使用固定大小存储的优点之一是它永远不会计算为NULL。在使用指针时,只需要空检查。诚然,在幕后,“readLineBuffer”可以用作指针,但它也是一个数组。尝试以下简单程序:

#include <stdio.h>

int main(int argc, const char* argv[])
{
    char buffer[1234];
    char* bufPointer = buffer; // yes, it looks like a pointer.
    printf("the size of buffer is %u but the size of bufPointer is %u\n",
           sizeof(buffer),
           sizeof(bufPointer));
    return 0;
}
(这就是为什么在C++11中他们添加了特殊的'nullptr'常量)

手动重复事物的大小是危险的。使用“sizeof()”命令

您确定文件中没有一行的长度超过200字节吗?想象一下:

fgets(buffer, 20, file);
现在想象一下这句台词:

1234567890123345678#这是评论

FGET将读取“123456789012345678#”,您的代码将删除尾随的“#”,并执行“puts”,这将向文件写入“1234567890012345678\n”。然后您将阅读“this is the comment”,而不是查找注释字符,并在文件中写一行新行“this is the comment”

第二,由于您将要迭代该行,您可能需要考虑以下任何一个:

a。自己迭代缓冲区 对于(int i=0;i b。使用strpbrk char*eol=strpbrk(“#\n”,readLineBuffer); if(eol!=NULL)//找到注释或行尾 *下线='\0'

这将使您的代码简化为以下内容。虽然这段代码将在“C++编译器”上编译,但它几乎是纯“C”

如果您想要处理和存储正在进行的实际信息,您将需要创建变量来存储它,在readLineBuffer中的每一行经过时编写代码进行检查/解析,并且您将想要学习使用诸如“sscanf”、“atoi”、“strtoul”等命令,最终你需要创建一些微型的状态机

或者,您可能希望研究一种脚本语言,如“Perl”或“Python”,它们是为类似这样的任务而设计的

# perl version

local $/ = /\n{2,}/;  # Read the file as paragraphs.
open(file, "font.dat") || die "Can't open font.dat";
my %data = ();
while ($line = <>) {
    $line =~ s/\s+#.*$//mg;    # Get rid of all the comments.
    $line =~ s/\n\n/\n/sg;     # Fix any blank lines we introduced.

    # Each data block starts with an ini-style label, that is a
    # line starting with a "[", followed by some word-characters (a-z, A-Z, 0-9)
    # and a closing "]", maybe with some whitespace after that.

    # Try to remove a label line, capturing the label, or skip this block.
    next unless $line =~ s/^ \[ (\w+) \] \s* \n+ //sx;

    # Store the remaining text into data indexed on the label.
    my ($label) = ($1);  # the capture
    $data{$label} = $line;
}

print("FONT_ID = $data{'FONT_ID'}\n");
#perl版本
本地$/=/\n{2,}/#以段落形式阅读文件。
打开(文件,“font.dat”)| | die“无法打开font.dat”;
我的%data=();
而($line=){
$line=~s/\s+#。*$//mg;#删除所有注释。
$line=~s/\n\n/\n/sg;#修复我们引入的任何空行。
#每个数据块都以ini样式标签开始,即
#以“[”开头的行,后跟一些单词字符(a-z、a-z、0-9)
#还有一个结尾“]”,后面可能有一些空格。
#尝试删除标签行、捕获标签或跳过此块。
除非$line=~s/^\[(\w+)\]\s*\n+//sx;
#将剩余文本存储到标签上索引的数据中。
我的($label)=(1美元)#捕获
$data{$label}=$line;
}
打印(“FONT_ID=$data{'FONT_ID'}\n”);
或者用perl编写

local $/ = /\n{2,}/;  # Read blocks separated by 2-or-more newlines (paragraphs)
die "Can't open file" unless open(file, "font.dat");
while (<>) {
    s/\s+#.*$//mg;
    s/\n{2,}/\n/sg;
    $data{$1} = $_ if (s/^\[(\w+)\][^\n]+\n+//s);
}
$fontId = ;
print("font_id = ", int($data{'FONT_ID'}), "\n");
local$/=/\n{2,}/#读取由2个或多个换行符(段落)分隔的块
模具“无法打开文件”,除非打开(文件,“font.dat”);
而(){
s/\s+#.$//mg;
s/\n{2,}/\n/sg;
$data{$1}=$\if(s/^\[(\w+\][^\n]+\n+//s);
}
$fontId=;
打印(“font\u id=”,int($data{'font\u id'}),“\n”);

< C++ >你知道{iO.f}流吗?它是一个文本文件,所以你不应该用二进制模式打开它。还有更好的方法可以在您刚读到的行中找到
“#”
(例如,如果您想继续使用仅限C的函数,请参见)。由于您使用的是Windows,您应该小心确保换行符实际上不是Windows换行符(
“\r\n”
)。谢谢您的提示,但是我如何读取它们的id标记?如何?或者使用,只是做一个普通的测试,但是我如何将下一行的id转换成代码中的某个变量呢?我对这个有点陌生…很棒的信息!谢谢你写的这篇好文章。我真的是初学者C和C++,只是阅读一些教程,并编写代码的基础上。再次感谢!拥有一种方便的脚本语言——javascript、perl、python等——非常有助于解决问题中棘手的、全局性的部分;“C”将迫使您在需要速度/性能时,将注意力集中在问题的实际计算部分。在学习C++的时候编写C代码是个陷阱。C++和面向对象代码实际上是关于离散地描述程序的问题、模式和特征。C是一个合理的方法来学习事物的OOP,只是要注意,好的C做的事情在C++中是非常糟糕的。
fgets(buffer, 20, file);
FILE *file = fopen("fonts.dat", "r");
if (file == NULL)
    return 1;

char readLineBuffer[200];
while (fgets(readLineBuffer, sizeof(readLineBuffer), file) != NULL)
{
    // find comment or end of line so we can truncate the line.
    char* eol = strpbrk(readLineBuffer, "#\n");
    if ( eol != NULL )
        *eol = '\0';
    puts(readLineBuffer);
}

fclose(file);

system("PAUSE");
return 0;
# perl version

local $/ = /\n{2,}/;  # Read the file as paragraphs.
open(file, "font.dat") || die "Can't open font.dat";
my %data = ();
while ($line = <>) {
    $line =~ s/\s+#.*$//mg;    # Get rid of all the comments.
    $line =~ s/\n\n/\n/sg;     # Fix any blank lines we introduced.

    # Each data block starts with an ini-style label, that is a
    # line starting with a "[", followed by some word-characters (a-z, A-Z, 0-9)
    # and a closing "]", maybe with some whitespace after that.

    # Try to remove a label line, capturing the label, or skip this block.
    next unless $line =~ s/^ \[ (\w+) \] \s* \n+ //sx;

    # Store the remaining text into data indexed on the label.
    my ($label) = ($1);  # the capture
    $data{$label} = $line;
}

print("FONT_ID = $data{'FONT_ID'}\n");
local $/ = /\n{2,}/;  # Read blocks separated by 2-or-more newlines (paragraphs)
die "Can't open file" unless open(file, "font.dat");
while (<>) {
    s/\s+#.*$//mg;
    s/\n{2,}/\n/sg;
    $data{$1} = $_ if (s/^\[(\w+)\][^\n]+\n+//s);
}
$fontId = ;
print("font_id = ", int($data{'FONT_ID'}), "\n");