将字符串地址传递给 fscanf() 可防止来自 运行 的不相关代码块

Passing address of a string to fscanf() prevented unrelated code-block from running

我一直在开发一个 C 小程序,该程序从文件中读取字符串,使用 crypt() 对其进行加密,然后将加密版本写入字符串。出于某种原因,我没有考虑并将 fscanf 调用写为:

fscanf( filename, "%s", &string );

这不起作用,因为字符串已经表示为指针,但这样做:

fscanf( filename, "%s", string );

这个逻辑(读取、测试、加密、打印)是循环完成的。在循环之前,我有几行代码将程序信息打印到日志文件:

fprintf( logfile, "Called as %s\n", executable );
/* Etc... */

在我意识到 fscanf 的错误之前,我注意到在程序收到 SIGSEGV 后,创建的日志文件是空的。起初我尝试了一个循环:

while(1)
{
  fprintf( logfile, "Looped!\n");
}

这一直有效,直到我输入读取、测试、加密、打印序列。我意识到我的错误是什么,但我的问题是: 为什么不正确地读取字符串(总是出现段错误)会阻止来自 运行 的完全不相关的代码块?

编辑:这是 "working" 代码(加密仍然有段错误):

fprintf( logfile, "Called as %s\n", executable );
fprintf( logfile, "Assigned pid %lu\n", pid );
fprintf( logfile, "Input File: %s\n", inputfilename );
fprintf( logfile, "Output File: %s\n", outputfilename );
fprintf( logfile, "Default BUFFER: %lu\n", BUFFER );
fprintf( logfile, "Crypt output sixe: %lu\n", CRYPT_OUTPUT_SIZE );
fprintf( logfile, "\n" );

/*  Try to set up space for strings */
fprintf( logfile, "Attempting to allocate %lu chars(%u) for plaintext string...\n", BUFFER,sizeof(char) );
char *plaintext_string = (char *) calloc( BUFFER, sizeof(char) );
if( plaintext_string == NULL )
{
    fprintf( logfile, "Errno %d; Error %s; Trying to allocate %lu chars(%u) for plaintext string\n",
    errno, strerror(errno), BUFFER,sizeof(char) );
    return(STRERROR);
}

fprintf( logfile, "Success; Now attempting to allocate %lu bytes for encrypted string...\n", CRYPT_OUTPUT_SIZE );
char *encrypted_string = (char *) calloc( CRYPT_OUTPUT_SIZE, sizeof(char) );
if( encrypted_string == NULL )
{
    fprintf( logfile, "Errno %d; Error %s; Trying to allocate %lu chars(%u) for encrypted string\n",
    errno, strerror(errno), (unsigned long) CRYPT_OUTPUT_SIZE, sizeof(char) );
    return(STRERROR);
}

fprintf( logfile, "\n" );

fprintf( logfile, "Entering main loop\n" );
while( TRUE )
{
    int res = fscanf( inputfile, "%s", plaintext_string );
    if( res == EOF )
    {
        fprintf( logfile, "Reached EOF in %s; Breaking from loop\n", inputfilename );
        break;
    }

    if( plaintext_string == NULL )
    {
        fprintf( logfile, "Errno %d; Error %s; String read in from %s was NULL\n", errno, strerror(errno), inputfilename);

        free(plaintext_string);
        free(encrypted_string);
        fclose(logfile);
        fclose(inputfile);

        return(STRERROR);
    }

    strcpy( encrypted_string, crypt( plaintext_string, SALT ) );
    if( encrypted_string == NULL )
    {
        fprintf( logfile, "Errno %d; Error %s; Encrypted string was NULL\n", errno, strerror(errno) );

        free(plaintext_string);
        free(encrypted_string);
        fclose(logfile);
        fclose(inputfile);

        return(STRERROR);
    }

    fprintf( outputfile, "%s\n", encrypted_string );

    /*  Clear the strings so no data is held    */
    *plaintext_string = NULL;
    *encrypted_string = NULL;
}

谢谢!

--乔丹。

写入日志文件默认是缓冲的。当程序因段错误而崩溃时,缓冲区永远不会被刷新。使用 setvbuf(logfile, _IONBF); 关闭缓冲或在您希望缓冲区转到文件时刷新缓冲区:

fprintf( logfile, "Called as %s\n", executable );
fflush(logfile);