アプリケーション開発ポータルサイト
ServerNote.NET
Amazon.co.jpでPC関連商品タイムセール開催中!
カテゴリー【C/C++
クオテーションに囲まれた文字列内の改行のみ消去するサンプル
POSTED BY
2023-07-24

データベースのカラム値には生の改行を入れられるので、当然ながら、ダンプした時も改行コードはそのまま出力され、たとえばこんな感じになる。

INSERT INTO trec VALUES('aaaaa''いいい\n
ううう\r\n
えええ\n
');

こうなると、ダンプをgrepやsedにかけて変換しようとするとき、いまいちうまく行かない。
必要ないなら元から改行をはじいて登録してれば良いのだが、既存の場合はやむを得ない。

なので標準入力群の''囲い文字列内の改行を消去して標準出力するサンプルを書いてみた。

C/C++delcrlf_inquot.cGitHub Source
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
  int bytes, in_quot = 0;
  char c, buf[2048], *p1, *p2, *p3, *p4;
  size_t psize;

  while (1) {
    bytes = fread(buf, 1, sizeof(buf) - 1, stdin);
    if (bytes <= 0) {
      break;
    }
    buf[bytes] = '\0';
    /* クオート内外問わず\r\n->\n,\r->\nと変換 */
    for (p1 = buf; (p2 = strchr(p1, '\r')) != NULL; p1 = p2 + 1) {
      *p2 = '\n';
      if (*(p2 + 1) == '\n') {
        p2++; /* \r\n->\n */
      } else if (*(p2 + 1) == '\0') {
        *p2 = '\0'; /* バッファの区切りで来てしまった場合消去 */
        break;
      }
    }
    for (p1 = buf;
         (p2 = strchr(p1, '\'')) != NULL || (p2 = strchr(p1, '\0')) != NULL;
         p1 = p2 + 1) {
      c = *p2;
      *p2 = '\0';
      if (in_quot) /* ここで\nを消去する */
      {
        for (p3 = p1; (p4 = strchr(p3, '\n')) != NULL; p3 = p4 + 1) {
          psize = (size_t)p4 - (size_t)p3;
          fwrite(p3, psize, 1, stdout);
        }
        fwrite(p3, strlen(p3), 1, stdout);
      } else {
        fwrite(p1, strlen(p1), 1, stdout);
      }
      *p2 = c;
      if (c == '\0') {
        break;
      } else {
        putchar(c);
        in_quot = in_quot ? 0 : 1;
      }
    }
  }
  return 0;
}

gcc delcrlf_inquot.c
./a.out < in_file > out_file

最初の構文も、

INSERT INTO trec VALUES('aaaaa''いいいうううえええ');

と出力してくれる。

※本記事は当サイト管理人の個人的な備忘録です。本記事の参照又は付随ソースコード利用後にいかなる損害が発生しても当サイト及び管理人は一切責任を負いません。
※本記事内容の無断転載を禁じます。
【WEBMASTER/管理人】
自営業プログラマーです。お仕事ください!
ご連絡は以下アドレスまでお願いします★

☆ServerNote.NETショッピング↓
ShoppingNote / Amazon.co.jp
☆お仲間ブログ↓
一人社長の不動産業務日誌
【キーワード検索】