简体   繁体   English

了解C字符串串联

[英]Understanding C String Concatenation

For an assesment in C i have to take two files with strings within them, and a string to concatenate them together eg: 对于用C进行的评估,我必须获取其中包含字符串的两个文件,以及将它们连接在一起的字符串,例如:

If file1 contains 如果file1包含

Now is the

time for all

good men to

come to the aid of

the party.

and file2 contains: 和file2包含:

alpha

beta

gamma

then the output from 然后从

scat XX file1 file2

(scat being the program name) (scat是程序名称)

should be 应该

Now is theXXalpha

time for allXXbeta

good men toXXgamma

come to the aid ofXX

the party.XX

and the output from 和来自的输出

scat XX file2 file1

should be 应该

alphaXXNow is the

betaXXtime for all

gammaXXgood men to

XXcome to the aid of

XXthe party.

In order to understand this i've been trying to play around with string concatenation trying to manually concat strings together. 为了理解这一点,我一直在尝试使用字符串连接尝试将字符串手动连接在一起。

My question is (A: how to i access individual lines of a file in c?) and B: if I manually input: 我的问题是(A:如何在c中访问文件的各个行?)和B:如果手动输入:

  char *str1 = "hello";

  char *str2 = "world";

how would i add these strings together without a predefined function. 没有预定义的函数,我怎么将这些字符串加在一起。 My thoughts initially were to use a for loop: 我最初的想法是使用for循环:

 for(str1; *str1 != '\0'; str1++)

     if(*str1 == '\0')

       *str1++ = *str2++;

my only issue is wouldn't this cause a seg fault due to memory access? 我唯一的问题是这是否会由于内存访问而导致段错误?

when i encounter a '\\0' in a string..how can i extend this string? 当我在字符串中遇到“ \\ 0”时。如何扩展此字符串? unless i just copy both strings into a new char str3[200] ? 除非我只是将两个字符串都复制到新的char str3 [200]中?

(all of the above is to try and help me understand how strings and string concat works, any assistance in learning this would be appreciated.) (以上所有内容都是为了帮助我理解字符串和字符串concat的工作原理,希望能对学习有所帮助。)

Euden 欧登

I'm not going to do it for you, but here are some tips/pitfalls. 我不会为您这样做,但是这里有一些提示/陷阱。

  1. Handle corner cases. 处理角盒。 What if the files don't have the same number of lines? 如果文件没有相同的行数怎么办?

  2. Unless you really have to support unlimited lines (ask your professor) I would suggest a buffer of 2048 characters for the input and 5000 for the output (2*2048 + concatenation string). 除非您真的必须支持无限制的行(请教您的教授),否则我建议输入的缓冲区为2048个字符,输出的缓冲区为5000(2 * 2048 +串联字符串)。

  3. You'll want to read using fgets into the input buffers for both files, and then concatenate them with strncat . 您需要使用fgets读取两个文件的输入缓冲区,然后将它们与strncat串联。

How you go about reading the lines from your input files should probably be based on what functions your professor has taught you or had you read about. 从输入文件中读取行的方式可能应该基于您的教授教给您的功能或您所阅读的内容。 Certainly not the best way to do it, but a simple way is to use fopen() to open the file, then getline() to read each line. 当然,这不是最好的方法,但是一种简单的方法是使用fopen()打开文件,然后使用getline()读取每一行。 This is simple but requires you to allocate excess buffer space (and risk a buffer overrun if you're not sure how much space you'll need). 这很简单,但是需要您分配多余的缓冲区空间(如果不确定是否需要多少空间,可能会导致缓冲区溢出)。 It also requires you to trim the \\n from each line of input. 它还要求您从输入的每一行中修剪\\ n。

As to concatenating without using the built-in function, your proposed method may have the problem you fear. 至于不使用内置函数进行连接,建议的方法可能会遇到您担心的问题。 You need to know how much space you have available to write into and if you go beyond that, you're asking for trouble (and you will receive it). 您需要知道可以写入多少空间,如果超出该范围,您就会遇到麻烦(并且您会收到麻烦)。 Creating a new buffer for the purpose of placing the output will keep you safe, but you suggest creating two new buffers; 为了放置输出而创建一个新的缓冲区将使您安全,但是建议您创建两个新的缓冲区。 only one is needed. 只需要一个。

If you need hints, review the source code behind Martin Broadhurst's Reading a Text File in C and the function strcat() . 如果需要提示,请查看Martin Broadhurst的“用C语言阅读文本文件”strcat()函数背后的源代码。 There are many places on the internet where source code for strcat() is available. 互联网上有很多地方都可以找到strcat()源代码。

Well, there is no need for string concatenation if the only goal is reading from two files, and writing to stdout, only a one-character buffer is sufficient, and a simple state machine will do. 好吧,如果唯一的目标是从两个文件读取并写入stdout,则只需要一个字符缓冲区就足够了,而一个简单的状态机就可以完成字符串连接。

#include <stdio.h>

int main (int argc, char **argv)
{
FILE *fp1, *fp2;
int ch, state ;

if (argc < 4) {
        fprintf(stderr, "Argc=%d, should be > 3\n", argc);
        return 0;
        }

for (state = 0; state < 42;     ) {
        switch (state) {
        case 0:
                fp1 = fopen (argv[2], "r"); if (!fp1) return 0;
                fp2 = fopen (argv[3], "r"); if (!fp2) { fclose (fp1); return 0;}
                state++;
        case 1:
                ch = fgetc(fp1);
                if (ch == EOF) state = 10;
                else if (ch == '\n') state =2;
                else putchar(ch);
                break;
        case 2:
                fputs( argv[1], stdout);
                state = 3;
        case 3:
                ch = fgetc(fp2);
                if (ch == EOF) state = 22;
                else if (ch == '\n') state =4;
                else putchar(ch);
                break;
        case 4:
                putchar(ch);
                state = 1;
                break;
        case 10: /* fp1 exhausted */
                ch = fgetc(fp2);
                if (ch == EOF) state = 30;
                else if (ch == '\n') state = 12;
                else {
                        fputs( argv[1], stdout );
                        putchar(ch);
                        state = 11;
                        }
                break;
        case 11:
                ch = fgetc(fp2);
                if (ch == EOF) state = 13;
                else if (ch == '\n') state = 12;
                else putchar(ch);
                break;
        case 12:
                putchar(ch);
                state = 10;
                break;
        case 13:
                putchar('\n');
                state = 30;
                break;
        case 20: /* fp2 exhausted */
                ch = fgetc(fp1);
                if (ch == EOF) state = 30;
                else if (ch == '\n') state = 21;
                else putchar(ch);
                break;
        case 21:
                fputs( argv[1], stdout);
                state = 22;
        case 22:
                putchar('\n');
                state = 20;
                break;
        case 30: /* both fp1+fp2 exhausted */

                fclose (fp1);
                fclose (fp2);
                state = 42;
                }
        }
return 0;
}

Disclaimer: don't try this at home. 免责声明:请勿在家中尝试此操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM