需要帮助来理解数组

Requiring help to understand arrays

我正在学习 C 中的数组,但我不明白为什么以下内容不正确?

#include <cs50.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <ctype.h>

int main(void)
{
    string plaintext = get_string();

    int x = 5;
    long long N = strlen(plaintext);
    string a = plaintext;
    long long c = 0;
    int z = x;

    for(int i = 0; i < N + (N/x) ; i++)
    {

        if( i == x)
        {
            a[c] = 32;
            c++;
            z = (z + x);
            //printf("%c\n", a[c]);           
        }

        a[c] = plaintext[i];
        //printf("%c\n", a[c]); 
        c++;
    }

    printf("%s\n", a);
}

它的意思是在每 x 个字符之后将空格插入文本字符串中...我知道它效率不高(我想我需要一种叫做指针的东西)但为什么它不起作用?我使用调试器检查了它,我的原始字符串似乎在不断变化......但是为什么呢?

假设 stringchar * 那么 texta 指向同一个字符串。这解释了为什么您的原始字符串会发生变化。您可以做的是:

string a= malloc(N+1 + N/x +1);

这会为一个新字符串分配 space,您可以在每 x 个字符后使用 space 将原始字符串复制到其中。当 xN 为奇数时,为空终止符加 1 和 1 "to be safe"。

#include <bits/stdc++.h>
using namespace std;
#define freinput "input.txt","r",stdin
#define freoutput "output.txt","w",stdout
#define mp make_pair
#define fi first
#define sc second
#define ellapse printf("Time : %0.3lf\n",clock()*1.0/CLOCKS_PER_SEC);
typedef long long ll;
typedef unsigned long int uld;
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int,int> pii;
string s;
string stringInsertion(int x,string neww){

    for(int i = 0;i<s.size();i++){
        if(i!=0 && i%x==0){
            neww=neww+' '+s[i];
        }
        else neww+=s[i];
    }
    return neww;
}
int main(){

    cin>>s;
    int x = 2;
    string neww="";
    cout<<stringInsertion(x,neww);
}

只需设置 x number.hope 这个帮助

好吧,让我们先做类似的事情:打印出带有spaces 的字符串。使用 i 遍历字符串。每次 ix 整除时,我们在打印字符之前打印一个 space,但不是在开头:

void print_spaced(const char *s, int x)
{
    int i;

    for (i = 0; s[i]; i++) {
        if (i && i % x == 0) putchar(' ');
        putchar(s[i]);
    }

    putchar('\n');
}

你不需要事先确定长度,因为你可以在遇到终止空字符时停止。也就是说,只要 s[i] 不为空,就继续。 (回想一下,s[i]s[i] != '[=20=]' 相同,类似地,ii != 0 相同。)

现在让我们用 spaced 输出字符串填充一个 char 数组,而不是打印它:

int space_out_unsafe(char *res, const char *s, int x)
{
    int i, k = 0;

    for (i = 0; s[i]; i++) {
        if (i && i % x == 0) res[k++] = ' ';
        res[k++] = s[i];
    }

    res[k] = '[=11=]';
    return k;
}

这个函数需要一个额外的参数:一个要填充的字符缓冲区。它有第二个索引,k,这是结果缓冲区的当前长度。每当我们在第一个版本中打印时,我们现在都会在字符串中附加一个字符:

res[k++] = '#';

Tis 覆盖当前结尾并在一个位置上移动k。我们不在最后写一个换行符,但我们必须以 null 终止结果。

但是有一个问题:缓冲区可能溢出;请注意我如何标记上面的函数 unsafe。 C 中的数组具有固定大小,并且在追加某些内容时不会自动增长。因此,将最大缓冲区大小 max 传递给函数并在附加之前检查溢出是一个好主意:

int space_out(char *res, int max, const char *s, int x)
{
    int i, k = 0;

    for (i = 0; s[i]; i++) {
        if (i && i % x == 0 && k < max - 1) res[k++] = ' ';
        if (k < max - 1) res[k++] = s[i];
    }

    res[k] = '[=13=]';
    return k;
}

您现在可以像这样使用此功能:

char res[20];

space_out(res, sizeof(res), "Doremifasola", 2);
puts(res);

还有其他方法可以做到这一点。您可以按照 Paul 的建议动态分配内存。这样,您可以满足您需要的额外 space,但您也让函数的调用者负责清理使用 free 分配的内存。动态分配内存是你第一周后要研究的事情。 :)

另一种可能是space原地取出字符串,即修改原始缓冲区的内容。不过,您仍然需要注意提供额外的 space。 (通常,当结果字符串较短时,例如过滤掉字符时,会使用就地中间化。)您还应该处理来自 和 的字符串,以免用 spaces 覆盖您稍后需要的数据。如果你有信心,这也是下周的练习。